Подготовительные шаги

# Установим рабочую директорию
setwd("~/Documents/GitHub/RProjects_EF/Networks")

Обработка данных и создание графа

# Загрузим данные для исследования: набор ребер и вершин
edges <- read.csv("edges_1.csv", header=T) 
colnames(edges) <- c('from', 'to', 'type1', 'type2', 'weight')

nodes <- unique(edges[c('from', 'type1')])
more_nodes <- unique(edges[c('to', 'type2')])

colnames(nodes) <- c('organisation', 'type')
colnames(more_nodes) <- c('organisation', 'type')

nodes <- rbind(nodes, more_nodes)
nodes <- unique(nodes[c('organisation', 'type')])
rownames(nodes) <- NULL
edges <- edges[c('from', 'to', 'weight')]

# Создадим также набор обратных величин для весов ребер (это пригодится нам в дальнейшем). Исходные веса нам уже не понадобятся
edges$weight <- 1 / edges$weight

net <- graph_from_data_frame(d=edges, vertices=nodes, directed=F)

V(net)$color <- ifelse( V(net)$type=="Business Enterprise", "red", 
  ifelse( V(net)$type=="Private not for profit", "purple", 
    ifelse( V(net)$type=="Government", "green", 
      ifelse( V(net)$type=="Higher Education", "blue", "black") 
    ) 
  ) 
)
head(V(net)$color, 10)
 [1] "red"    "red"    "red"    "red"    "red"    "red"    "purple" "green"  "purple" "red"   

Поясним, почему в дальнейшем будем работать именно с обратными весами: Кратчайший путь и кратчайшее расстояние в данной задаче будут представлять собой не то же самое, что и в задаче с издержками перевозок или длинами расстояний между вершинами в качестве весов ребер. Отрицательные веса мы не используем, потому что алгоритм Дейкстры работает с неотрицательными весами ребер, поэтому далее мы оперируем с обратными весами, т.к., на наш взгляд, этот выбор является наиболее оптимальным для преодоления возникших трудностей.


Исследовательский вопрос

Исследовательский вопрос: Какие есть способы улучшения взаимодействия учреждений высшего образования Новой Зеландии (если это вообще требуется)?

Наше исследование показывает, что возможно повысить эффективность небольших университетов посредством увеличения сотрудничества с крупными, которые в свою очередь имеют тесное сотредничество с бизнесом.

Детали см. в Задании 6.


Анализ датасета

Описание датасета

Датасет представляет из себя множество вершин с качественными характеристиками и множество ребер с числовыми характеристиками (весами).

Вершинами являются организации Новой Зеландии, которые занимаются написанием научных статей в качестве одного из видов деятельности. Качественной характеристикой вершин является вид организации (государственная организации, высшее учебное заведение, коммерческое предприятие и частное некоммерческое предприятие). Всего в датасете 1511 вершин.

Между i-ой и j-ой вершинами (организациями) существует ребро, если за период 2010-2015 гг. на Scopus была опубликована хотя бы одна статья, хотя бы один автор которой числится в организации i, а другой автор – в организации j. Всего в датасете 4273 ребра.

Вес ребра равен количеству совместных опубликованных научных работ. Если вес ребра между i-ой и j-ой вершиной равен 3, то это означает, что за указанный период на Scopus было опубликовано 3 научные работы, у которых хотя бы один автор числится в организации i, а другой — в организации j.


Задание 2

При использовании нескольких пакетов для работы с графами не оказалось возможным интерпретируемо визуализировать граф полностью. Поэтому для отображения структуры нашей сети найдем 100 самых центральных по степени вершин и представим связи между ними при помощи пакета ggraph.

V(net)$degrees <- degree(net)
nodes$degrees <- V(net)$degrees

for_vis_n <- nodes[order(-nodes$degrees),][1:100, 1:2]
for_vis_e <- edges[(edges$from %in% for_vis_n$organisation & edges$to %in% for_vis_n$organisation),]

for_vis_net <- graph_from_data_frame(d=for_vis_e, vertices=for_vis_n, directed=F)
V(for_vis_net)$degrees <- degree(for_vis_net)

for_vis_net %>%
  ggraph(layout='graphopt') +
  geom_node_point(aes(color = type, size=round(degrees/20))) +
  geom_edge_link(alpha = 0.05) +
  theme_void() +
  ggtitle("Network of New Zealand organisations")

Как можно увидеть, среди 100 самых центральных вершин с количественной точки зрения преобладают организации государственного сектора, однако самыми крупными здесь являются новозеландские университеты. Первые 5 мест по числу совместных научных работ принадлежат именно им, лидером по данному показателю является Университет Окленда, самый крупный и престижный университет Новой Зеландии.

Рассчитаем базовые параметры нашего графа. Так как весами дуг в данном случае является число совместных работ, то есть “сила связи” двух вершин, будем использовать обратные веса для подсчета центральностей через кратчайшие пути. Это довольно разумно, так как от написания дополнительной общей работы прирост в силе связи двух организаций должен монотонно снижаться, как и разница в пути до соседа.

#Считаем базовые параметры графа

# Density
# The proportion of present edges from all possible ties.
p <- edge_density(net)

# связность сети
no <- igraph::components(net)$no # в пакете statnet такое же название
csize <- igraph::components(net)$csize
csize
 [1] 1463    2    2    2    3    2    2    2    2    2    2    2    2    2    2    2    2    2    2    2
[21]    2    2    3    2
# Diameter (longest geodesic distance) (если несколько компонент, то диаметр самой большой)
# Note that edge weights are used by default, unless set to NA.
diam <- diameter(net, weights=NA)
diam_w <- diameter(net)
path <- get_diameter(net, weights=NA)
path_w <- get_diameter(net)
path
+ 7/1511 vertices, named, from 83998d9:
[1] Dairy Production Systems Ltd.  Straven Road Veterinary Centre AgResearch                    
[4] Auckland Council               Auckland District Health Board New Zealand National Eye Bank 
[7] Project Litefoot Trust        
path_w
+ 9/1511 vertices, named, from 83998d9:
[1] Dairy Production Systems Ltd.     Straven Road Veterinary Centre    AgResearch                       
[4] Massey University                 University of Auckland            Victoria University of Wellington
[7] GNS Science                       ECoast Limited                    Dumpark Data Science             
# рассчитаем кратчайшие пути
# Average path length 
# The mean of the shortest distance between each pair of nodes in the network 
# (in both directions for directed graphs). 
m_dist <- mean_distance(net, weights=NA)
m_dist_w <- mean_distance(net)

Плотность нашего графа составляет 0.0037. Такая низкая плотность (вероятность образования связи) довольно естественная для вероятности написания научной работы. Наша сеть имеет 24 компонент связности: одна главная, соединяющая практически все вершины, а все остальные имеют по 2-3 вершины. Диаметр (наибольший из кратчаших путей) имеет длину 4.01, или 6, если брать единичные веса для всех дуг.

Изучим соседство самой центральной вершины — Оклендского Университета (с кем чаще всего взаимодействует наиболее престижный ВУЗ страны):

# We can also easily identify the immediate neighbors of a vertex.
# The 'neighbors' function finds all nodes one step out from the focal actor.
# To find the neighbors for multiple nodes, use 'adjacent_vertices()'.
d <- data.frame(neighbors(net, V(net)["University of Auckland"], mode="total")$type)
groups <- as.data.frame(table(d))[, 2]
pie(groups, labels=paste0(as.data.frame(table(d))[, 1], ', ',round(groups/sum(groups)*100, digits=1), '%'), 
    col=c(5, 2, 3, 4), main='Neighbors of University of Auckland')

# To find node neighborhoods going more than one step out, use function 'ego()'
# with parameter 'order' set to the number of steps out to go from the focal node(s).
neigh2 <- data.frame(ego(net, order = 2, nodes = V(net)["University of Auckland"])[[1]]$type)
groups2 <- as.data.frame(table(neigh2))[, 2]
pie(groups2, labels=paste0(as.data.frame(table(neigh2))[, 1], ', ',round(groups2/sum(groups2)*100, digits=1), '%'), 
    col=c(5, 2, 3, 4), main='Two-step neighbors of University of Auckland')

Довольно ожидаемо, что чаще всего в написании научных работ такой успешный университет сотрудничает с индустрией. Это подтвеждает наше предположение о том, успех научной работы зависит от работы с бизнесом. В ближайшем окружении данной организации также принято вести исследования с индустрией.

Сравним нашу сеть с теоритическими моделями случайного графа на основе распределения числа их соседей, диаметра, среднего кратчайшего пути и числа компонент связности. Начнем с модели случайного графа Эрдеша-Реньи.

#Генерируем модели случайного графа erdos.renyi
p <- edge_density(net)

random_model <- erdos.renyi.game(n=gorder(net), p.or.m=p, type='gnp')
par(mfrow = c(1, 2))
hist(degree(net), main = "Histogram of node degree", breaks = 1:vcount(net)-1, prob = TRUE, xlim=range(c(0, 20)))
hist(degree(random_model), main = "Histogram of node degree", breaks = 1:vcount(net)-1, prob = TRUE, xlim=range(c(0, 20)))
par(mfrow = c(1, 1))


gl <- vector('list', 100)
m <- rep(NA, 100)
d <- rep(NA, 100)
a <- rep(NA, 100)
for (i in 1:100){
  gl[[i]] <- erdos.renyi.game(n=gorder(net), p.or.m=p, type='gnp')
  m[i] <- mean_distance(gl[[i]])
  d[i] <- diameter(gl[[i]])
  a[i] <- igraph::components(gl[[i]])$no
}
mean_distance <- m
hist(mean_distance, xlim=range(c(min(m, mean_distance(net)), max(m, mean_distance(net)))))
abline(v=mean_distance(net), col='red', lty=3, lwd=2) 


diameter <- d
hist(diameter, xlim=range(c(min(d, diameter(net, weights=NA)), max(d, diameter(net, weights=NA)))))
abline(v=diameter(net, weights=NA), col='red', lty=3, lwd=2) 


number_of_components <- a
hist(number_of_components, xlim=range(c(0, 25)))
abline(v=igraph::components(net)$no, col='red', lty=3, lwd=2)

Как можно заметить, все рассматриваемые показатели нашей сети значимо отличаются от модельных, значит, структуру нашей сети нельзя описать данным образом.

Обратимся к модели “Малого мира” с регулярной решеткой. Однако в этом случае сперва нужно подобрать гиперпараметр — долю переприсоединенных дуг.

#Генерируем модели случайного графа с регулярной решеткой
n_of_nei <- mean(degree(net))
diam_net <- diameter(net, weights=NA)
#Ищем оптимальное значение p
mean_dist_net <- mean_distance(net)
model <- vector('list', 100)
m <- rep(NA, 100)
d <- rep(NA, 100)
res <- rep(NA, 100)
for (i in 1:100){
  model[[i]] <- sample_smallworld(dim = 1, size = gorder(net), nei = n_of_nei, p = i/100)
  m[i] <- mean_distance(model[[i]])
  d[i] <- diameter(model[[i]])
  res[i] <- ((m[i]-mean_dist_net)^2+(d[i]-diam_net)^2)^(1/2) 
}

# p = 0.99

random_model <- sample_smallworld(dim = 1, size = gorder(net), nei = n_of_nei, p = 0.99)
par(mfrow = c(1, 2))
hist(degree(net), main = "Histogram of node degree", breaks = 1:vcount(net)-1, prob = TRUE, xlim=range(c(0, 30)))
hist(degree(random_model), main = "Histogram of node degree", breaks = 1:vcount(net)-1, prob = TRUE, xlim=range(c(0, 30)))
par(mfrow = c(1, 1))


gl <- vector('list', 100)
m <- rep(NA, 100)
d <- rep(NA, 100)
a <- rep(NA, 100)
for (i in 1:100){
  gl[[i]] <- sample_smallworld(dim = 1, size = gorder(net), nei = n_of_nei, p = 0.99)
  m[i] <- mean_distance(gl[[i]])
  d[i] <- diameter(gl[[i]])
  a[i] <- igraph::components(gl[[i]])$no
}
mean_distance <- m
hist(mean_distance, xlim=range(c(min(m, mean_distance(net)), max(m, mean_distance(net)))))
abline(v=mean_distance(net), col='red', lty=3, lwd=2) 


diameter <- d
hist(diameter, xlim=range(c(min(d, diameter(net, weights=NA)), max(d, diameter(net, weights=NA)))))
abline(v=diameter(net, weights=NA), col='red', lty=3, lwd=2) 


number_of_components <- a
hist(number_of_components, xlim=range(c(0, 25)))
abline(v=igraph::components(net)$no, col='red', lty=3, lwd=2)

Аналогично предыдущему случаю, данная модель плохо описывает структуру нашего графа. Значимо совпадает лишь диаметр, так как по нему в том числе происходил подбор гиперпараметра.

Рассмотрим также схожесть с моделью Барабаши-Альберта, включающей предпочтительное присоединение к наиболее центральным вершинам.

# Генерируем модель Барабаши-Альберта
#Ищем оптимальное значение power
model <- vector('list', 100)
res <- rep(NA, 40)
m <- rep(NA, 100)
d <- rep(NA, 100)
for (i in c(1:40)){
  model[[i]] <- sample_pa(n = gorder(net), power = i/10, directed = FALSE)
  m[i] <- mean_distance(model[[i]])
  d[i] <- diameter(model[[i]])
  res[i] <- ((m[i]-mean_dist_net)^2+(d[i]-diam_net)^2)^(1/2) 
}

#power=2.15

random_model <- sample_pa(n = gorder(net), power = 2.15, directed = FALSE)
par(mfrow = c(1, 2))
hist(degree(net), main = "Histogram of node degree", breaks = 1:vcount(net)-1, prob = TRUE, xlim=range(c(0, 20)))
hist(degree(random_model), main = "Histogram of node degree", breaks = 1:vcount(net)-1, prob = TRUE, xlim=range(c(0, 20)))
par(mfrow = c(1, 1))


gl <- vector('list', 100)
m <- rep(NA, 100)
d <- rep(NA, 100)
a <- rep(NA, 100)
for (i in 1:100){
  gl[[i]] <- sample_pa(n = gorder(net), power = 2.15, directed = FALSE)
  m[i] <- mean_distance(gl[[i]])
  d[i] <- diameter(gl[[i]])
  a[i] <- igraph::components(gl[[i]])$no
}
mean_distance <- m
hist(mean_distance, xlim=range(c(min(m, mean_distance(net)), max(m, mean_distance(net)))))
abline(v=mean_distance(net), col='red', lty=3, lwd=2) 


diameter <- d
hist(diameter, xlim=range(c(min(d, diameter(net, weights=NA)), max(d, diameter(net, weights=NA)))))
abline(v=diameter(net, weights=NA), col='red', lty=3, lwd=2) 


number_of_components <- a
hist(number_of_components, xlim=range(c(0, 25)))
abline(v=igraph::components(net)$no, col='red', lty=3, lwd=2)

Как мы получили, данная модель тоже не подходит для описания структуры новозеландской сети: все статистически значимо отличается, кроме параметра, по которому проходил подбор гиперпараметра.

Выводы

Выводы по Заданию 2: Ни одна из теоретических моделей, известных нам, не описывает структуры нашего графа достаточно точно.


Задание 3

В этом задании нам предлагается посчитать различные меры центральности вершин и сделать содержательные выводы на основе полученных расчетов.

Замечание: Для анализа используем обратные веса, т.к. их использование делает осмысленным расчет центральности по близости и кратчайшему пути, но не искажает остальных мер центральности вершин.

Центральность по степени

Для начала посчитаем центральность по степени:

deg <- degree(net)

# plot(net, vertex.label=NA, layout=layout_with_fr, vertex.size=deg)

Теперь построим гистограмму распределения степеней вершин:

# гистограмма степеней вершин
hist(deg, main="Histogram of node degree", breaks=50, prob=TRUE) 

# распределение степеней вершин

mean(deg) # Средняя степень вершины по графу
[1] 5.655857
# ~ 5.66
Mode(deg) # Модальная степень вершин графа
[1] 1
attr(,"freq")
[1] 599
# 1 -> 599 раз
median(deg) # Медиана степеней вершин
[1] 2
# ~ 2
top_10_degree <- tail(sort(deg), 10) # топ-10 по степеням
top_10_degree # в топе - 7 университетов, 3 гос. учреждения
 Canterbury District Health Board                        AgResearch             University of Waikato 
                              121                               126                               136 
   Auckland District Health Board                    AUT University Victoria University of Wellington 
                              143                               145                               204 
         University of Canterbury                 Massey University               University of Otago 
                              241                               310                               406 
           University of Auckland 
                              551 

Вывод: Центральность вершин по степени не зависит от весов. Подавляющее большинство вершин имеет степень, меньшую 50. Так, медиана кол-ва соседей равняется 2. В среднем у вершины такого графа степень равна 5.66. Наиболее часто встречающаяся степень вершины — 1, которая встречается 599 раз. Если мы посмотрим 10 вершин с наибольшим числом соседей, то окажется, что 7 из них являются университетами, в числе которых крупнейший — университет Окленда (степень вершины максимальная — 551). Оставшиеся 3 организации являются государственными: 2 департамента здравоохранения и 1 исследовательская компания. Степень у всех вершин, входящих в топ-10, > 100.

Центральность по близости

Далее рассчитаем центральность по близости двумя способами: В первом варианте все веса ребер графа являются 1, в другом используются обратные веса ребер.

clos1 <- closeness(net, weights=NA) # Первый способ - без учета весов
# clos1

plot(net, vertex.label=NA, layout=layout_with_fr, vertex.size=clos1 * 50)

top_10_clos1 <- tail(sort(clos1), 10) 
# Вектор-топ 42 также будет единичным, а вот вектор-топ 43 уже нет
top_10_clos1
  Reveal Infrastructure Ltd.          Napier City Council   RATO Natural Health Clinic 
                           1                            1                            1 
Stahlton Engineered Concrete        Katipo Communications     Workwise Employment Ltd. 
                           1                            1                            1 
                  Northpower   New Zealand Stock Exchange           Real Time Genomics 
                           1                            1                            1 
    Rotary Club of Riccarton 
                           1 
bottom_10_clos1 <- head(sort(clos1), 10)
bottom_10_clos1
                                         Tauranga City Council 
                                                  0.0001571092 
                                        Project Litefoot Trust 
                                                  0.0001703868 
                                          Dumpark Data Science 
                                                  0.0001706193 
                                 Dairy Production Systems Ltd. 
                                                  0.0001720282 
                                 SciCon Scientific Consultants 
                                                  0.0001725923 
New Zealand Employment Service and Work and Income New Zealand 
                                                  0.0001773050 
                                               IWM Consultancy 
                                                  0.0001779676 
                                        PLANTwise Services Ltd 
                                                  0.0001779676 
                                   Care of Orca Research Trust 
                                                  0.0001794044 
                                    Southern Veterinary Centre 
                                                  0.0001818843 
clos1["University of Auckland"]
University of Auckland 
          0.0004175365 
clos2 <- closeness(net)
# clos2

plot(net, vertex.label=NA, layout=layout_with_fr, vertex.size=clos2 * 50)

top_10_clos2 <- tail(sort(clos2), 10) 
top_10_clos2
  Workwise Employment Ltd.                 Northpower New Zealand Stock Exchange 
                       1.0                        1.0                        1.0 
        Real Time Genomics   Rotary Club of Riccarton      Bio Soil and Crop Ltd 
                       1.0                        1.0                        1.2 
           PollenPlus Ltd.               GroPlus Ltd.           Blues Rugby Club 
                       1.2                        1.5                        2.0 
         Highlanders Rugby 
                       2.0 
bottom_10_clos2 <- head(sort(clos2), 10)
bottom_10_clos2
                                          Dumpark Data Science 
                                                  0.0002501171 
                                 Dairy Production Systems Ltd. 
                                                  0.0002502698 
New Zealand Employment Service and Work and Income New Zealand 
                                                  0.0002504864 
                                        Project Litefoot Trust 
                                                  0.0002504870 
                                         Tauranga City Council 
                                                  0.0002955979 
                                                Port Otago Ltd 
                                                  0.0003060701 
                                                 Travel Clinic 
                                                  0.0003065386 
                                         Dobbie Engineers Ltd. 
                                                  0.0003069975 
                                        NZ Strong Construction 
                                                  0.0003069975 
                                     Pulp Mill Technical Group 
                                                  0.0003069975 
clos2["University of Auckland"]
University of Auckland 
          0.0009338331 

Вывод: В обоих случаях максимальная центральность вершин будет составлять 1. В нашем графе существует 21 пара вершин, которая связана лишь между собой и более ни с кем (из рассчета для графа с единичными весами ребер). Из них лишь 5 организаций работали совместно более 1 раза (из рассчета для графа с обратными весами). Топ-10 центральных вершин по близости и топ-10 по степени уже существенно различаются. Так, центральность по близости университета Окленда составит 4.1753653^{-4} в первом случае и 4.1753653^{-4}. Т.е. round(1 / clos1["University of Auckland"]) или round(1 / clos2["University of Auckland"]) — сумма длин всех путей от университета Окленда до любой другой вершины в зависимости от метода рассчета.

Центральность по кратчайшему пути

betw1 <- betweenness(net, weights=NA)
head(betw1)
           45 South Management Ltd.                          Abacus ALS 
                             0.0000                              0.0000 
                     AbacusBio Ltd.                   ABB Power Quality 
                           228.0179                              0.0000 
ABI Rehabilitation New Zealand Ltd.              AC Research Associates 
                             0.0000                              0.0000 
top_10_betw1 <- tail(sort(betw1), 10)
top_10_betw1
   Auckland District Health Board           Plant and Food Research                        AgResearch 
                         44138.73                          55148.49                          61204.78 
            University of Waikato                    AUT University Victoria University of Wellington 
                         62949.44                          64866.37                          84858.46 
         University of Canterbury                 Massey University               University of Otago 
                        130456.08                         194334.96                         231358.36 
           University of Auckland 
                        385421.47 
bottom_10_betw1 <- head(sort(betw1), 10)
bottom_10_betw1
                45 South Management Ltd.                               Abacus ALS 
                                       0                                        0 
                       ABB Power Quality      ABI Rehabilitation New Zealand Ltd. 
                                       0                                        0 
                  AC Research Associates      Academic Colleges Group New Zealand 
                                       0                                        0 
Action on Smoking and Health New Zealand                            Active Health 
                                       0                                        0 
                         Ade Consultants                   Adidas Sports Medicine 
                                       0                                        0 
betw1["University of Auckland"]
University of Auckland 
              385421.5 
betw2 <- betweenness(net)
head(betw2)
           45 South Management Ltd.                          Abacus ALS 
                                  0                                   0 
                     AbacusBio Ltd.                   ABB Power Quality 
                                  1                                   0 
ABI Rehabilitation New Zealand Ltd.              AC Research Associates 
                                  0                                   0 
top_10_betw2 <- tail(sort(betw2), 10)
top_10_betw2
   Auckland District Health Board           Plant and Food Research                    AUT University 
                         48988.50                          57655.33                          74583.33 
            University of Waikato                        AgResearch Victoria University of Wellington 
                         81434.50                          96575.50                         139495.17 
         University of Canterbury                 Massey University               University of Otago 
                        198521.67                         323919.17                         340995.17 
           University of Auckland 
                        815924.25 
bottom_10_betw2 <- head(sort(betw2), 10)
bottom_10_betw2
                45 South Management Ltd.                               Abacus ALS 
                                       0                                        0 
                       ABB Power Quality      ABI Rehabilitation New Zealand Ltd. 
                                       0                                        0 
                  AC Research Associates      Academic Colleges Group New Zealand 
                                       0                                        0 
       Accident Compensation Corporation Action on Smoking and Health New Zealand 
                                       0                                        0 
                           Active Health                Acurity Health Group ltd. 
                                       0                                        0 
betw2["University of Auckland"]
University of Auckland 
              815924.2 

Вывод: При разных методах минимальные значения центральности у вершин будут равны 0. Это вершины, расположенные на периферии графа, или те, которые вовсе имеют всего одного соседа (например, та 21 пара вершин). Максимальные центральности вершин превышают 40 000 в топ-10. В обоих случаях университет Окленда на первом месте (3.8542147^{5} и 8.1592425^{5}). Значительное число кратчайших путей между любыми двумя вершинами проходит именно через данный университет.

Центральность по собственному значению

eig1 <- eigen_centrality(net, weights = NA)
# head(eig1)

top_10_eig1 <- tail(sort(eig1$vector), 10)
top_10_eig1
                       AgResearch    Auckland District Health Board  Canterbury District Health Board 
                        0.3760716                         0.4334652                         0.4357203 
            University of Waikato                    AUT University Victoria University of Wellington 
                        0.4373508                         0.4700463                         0.5846012 
         University of Canterbury                 Massey University               University of Otago 
                        0.5943213                         0.6779365                         0.8521192 
           University of Auckland 
                        1.0000000 
bottom_10_eig1 <- head(sort(eig1$vector), 10)
bottom_10_eig1
                                  Highlanders Rugby                                    Growth Solutionz 
                                       3.407685e-18                                        3.423996e-18 
                                           FEM Ltd. New Zealand Rock Lobster Industry Council (NZ RLIC) 
                                       3.524028e-18                                        3.563296e-18 
                                        GHD Limited                                 Napier City Council 
                                       3.577456e-18                                        3.578251e-18 
                           Rotary Club of Riccarton                              Milner Consulting Ltd. 
                                       3.585397e-18                                        3.585975e-18 
                                           NetValue                        Crown Fibre Holdings Limited 
                                       3.598880e-18                                        3.629860e-18 
eig2 <- eigen_centrality(net)
# head(eig2)

top_10_eig2 <- tail(sort(eig2$vector),10)
top_10_eig2
                             NIWA             University of Waikato                    AUT University 
                        0.1576988                         0.1897041                         0.1992335 
 Canterbury District Health Board    Auckland District Health Board Victoria University of Wellington 
                        0.2127479                         0.2346215                         0.2896466 
         University of Canterbury                 Massey University               University of Otago 
                        0.3085040                         0.4043171                         0.6707261 
           University of Auckland 
                        1.0000000 
bottom_10_eig2 <- head(sort(eig2$vector),10)
bottom_10_eig2
                            Alzheimers Northland                                  AP EnerTec Ltd. 
                                               0                                                0 
Aviation Industry Association of New Zealand Inc                            Bio Soil and Crop Ltd 
                                               0                                                0 
                                Blues Rugby Club                    Bruce Shallard and Associates 
                                               0                                                0 
                      ChangeMakers Refugee Forum                      Chatham Rock Phosphate Ltd. 
                                               0                                                0 
                      Chilton Saint James School                     Crown Fibre Holdings Limited 
                                               0                                                0 

Вывод: Минимальные значения центральностей по собственному значению также составляют 0. Наибольшую же имеет университет Окленда. Его высокий показатель говорит, что сам университет связан со многими вершинами, которые в свою очередь имеют также высокое значение центральности.

Выводы

# объединим все центральности в один датафрейм и посмотрим корреляции в двух вариантах 
df1 <- data.frame(deg, clos1, betw1, eig1$vector)
cor(df1)
                    deg       clos1       betw1 eig1.vector
deg          1.00000000 -0.03452649  0.96148582   0.8926645
clos1       -0.03452649  1.00000000 -0.01592647  -0.1091064
betw1        0.96148582 -0.01592647  1.00000000   0.7596773
eig1.vector  0.89266448 -0.10910642  0.75967732   1.0000000
df2 <- data.frame(deg, clos2, betw2, eig2$vector)
cor(df2)
                    deg       clos2       betw2 eig2.vector
deg          1.00000000 -0.03349182  0.90929438   0.8418800
clos2       -0.03349182  1.00000000 -0.01198628  -0.1332681
betw2        0.90929438 -0.01198628  1.00000000   0.7737961
eig2.vector  0.84188004 -0.13326806  0.77379607   1.0000000

Вывод: Составив корреляционные матрицы заметим, что существует высокая корреляция между следующими парами центральностей вершин: по степени - по кратчайшему расстоянию, по степени - по собств. значению и по собств. значению - по кратчайшему расстоянию

Сравним, какие организации попадали в топы по центральностям (исключая центральность по близости).


corr1 <- data.frame(
  names(top_10_degree), 
  names(top_10_betw1), 
  names(top_10_eig1)
)
corr1

corr2 <- data.frame(
  names(top_10_degree), 
  names(top_10_betw2), 
  names(top_10_eig2)
)
corr2

Выводы по Заданию 3: Сравнив топы по максимальным центральностям (за исключением топа центральностей по близости из-за малого количества соседей [порядка 1]), заметим, что по трем центральностям первую пятерку занимают одни и те же организации: университет Окленда, университет Отаго, университет Мэсси, университет Кантербери и Викторианский университет Веллингтона.


Задание 4

В Задании 4 нам предлагается рассчитать ассортативность и гомофилию для графа. Начнем исследование данных с ассортативности:

Ассортативность

# Возникли проблемы с вычислением ассортативности через
# assortativity_nominal(net, types=V(net)$type, directed=F) 
# Предупреждение: в результате преобразования созданы NA
# [1] NaN
assortativity_nominal(net, types=V(net)$type, directed=F)
Предупреждение: в результате преобразования созданы NA
[1] NaN
# Поэтому было принято решение создать новый столбец с закодированными строками

V(net)$num_type <- ifelse( V(net)$type=="Business Enterprise", 1, 
                          ifelse( V(net)$type=="Private not for profit", 2, 
                              ifelse( V(net)$type=="Government", 3, 
                                  ifelse( V(net)$type=="Higher Education", 4, 0) 
                              ) 
                          ) 
                       )
assort_nom <- assortativity_nominal(net, types=V(net)$num_type, directed=F) 
assort_nom # -0.05876298
[1] -0.05876298
# значение ассортативности не зависит от конкретных чисел
V(net)$num_type1 <- ifelse( V(net)$type=="Business Enterprise", 2, 
                           ifelse( V(net)$type=="Private not for profit", 7, 
                               ifelse( V(net)$type=="Government", 5, 
                                  ifelse( V(net)$type=="Higher Education", 10, 0) 
                               ) 
                           ) 
                        )
assortativity_nominal(net, types=V(net)$num_type1, directed=F) # -0.05876298
[1] -0.05876298
# считаем ассортативность по степени вершины
assort_deg <- assortativity_degree(net, directed=F) # -0.3361749
assort_deg
[1] -0.3361749

Обобщение результатов: Ассортативность в графе по типу вершин примерно равна -0.059. Это означает, что мы не можем утверждать наличие предпочтительного присоединения узлов сети к своему типу (среди узлов в общем, т.е. среди узлов всех типов).

Ассортативность по степени вершины составляет примерно -0.336, что говорит о предпочтительном присоединении узлов к вершинам с относительно небольшим количеством соседей.

Для выявления более точного эффекта предпочтительного присоединения именно среди университетов (что интересует нас в рамках исследовательского вопроса) рассчитаем показатели гомофилии для университетов и других типов институтов.

Нами было принято решение рассчитать dyadicity (ее посчитаем только для одного случая, т.к. она не будет меняться при различных разбиениях) и heterophilicity учреждений высшего образования для следующих разделений на подгруппы: - Higher Education vs все остальные - Higher Education vs Business Enterprise - Higher Education vs Government.

Замечание: Влиянием Private not for profit можно пренебречь.

Higher Education vs все остальные

p <- edge_density(net)
p # 0.003745601
[1] 0.003745601
n_c <- sum( V(net)$type == 'Higher Education' )
n_c # 54
[1] 54
exp_diad_uni <- n_c * (n_c - 1) / 2 * p
exp_diad_uni # 5.359955
[1] 5.359955
unis <- V(net)[which( V(net)$type == 'Higher Education' )]
unis <- names(unis)
# unis

m_c <- 0

for (row in 1:nrow(edges)) {
  from_obj <- edges[row, 'from']
  to_obj <- edges[row, 'to']
  
  if ( (from_obj %in% unis) && (to_obj %in% unis) ) {
    m_c <- m_c + 1
  }
}

m_c # 172
[1] 172
diadicity_uni <- m_c / exp_diad_uni 
diadicity_uni # 32.08982
[1] 32.08982
# 2-й способ посчитать dyadicity
uni_net <- induced_subgraph( 
  net, 
  v=V(net)[which( V(net)$type == 'Higher Education' )] 
)
# uni_net
# V(uni_net)$type # проверяем, что все вершины в новом графе вузы

edge_density(net) # 0.003745601
[1] 0.003745601
edge_density(uni_net) # 0.1201957
[1] 0.1201957
edge_density(uni_net) / edge_density(net) # 32.08982
[1] 32.08982
n_c # 54
[1] 54
p # 0.003745601
[1] 0.003745601
n_nc <- sum( V(net)$type != 'Higher Education' )
n_nc # 1457
[1] 1457
exp_hetero_uni <- n_nc * n_c * p
exp_hetero_uni # 294.6964
[1] 294.6964
m_mixed <- 0

for (row in 1:nrow(edges)) {
  from_obj <- edges[row, 'from']
  to_obj <- edges[row, 'to']
  
  if ( (from_obj %in% unis) && !(to_obj %in% unis) ) {
    m_mixed <- m_mixed + 1
  }
  if ( !(from_obj %in% unis) && (to_obj %in% unis) ) {
    m_mixed <- m_mixed + 1
  }
}

m_mixed # 2051
[1] 2051
heterophilicity_uni <- m_mixed / exp_hetero_uni
heterophilicity_uni # 6.959706
[1] 6.959706

Higher Education vs Business Enterprise

# uni_biz_net <- induced_subgraph( 
#   net, 
#   v=V(net)[which( 
#     (V(net)$type == 'Higher Education') || (V(net)$type == 'Business Enterprise') 
#       )] 
# )
uni_biz_net <- induced_subgraph( 
  net, 
  v=V(net)[which( V(net)$type %in% c('Higher Education', 'Business Enterprise') )] 
)
# uni_biz_net
# V(uni_biz_net)$type

uni_wout_biz_net <- induced_subgraph( 
  uni_biz_net, 
  v=V(uni_biz_net)[which( V(uni_biz_net)$type == 'Higher Education' )] 
)
# uni_wout_biz_net
# V(uni_wout_biz_net)$type


p_uni_vs_biz <- edge_density(uni_biz_net)
p_uni_vs_biz # 0.003036165
[1] 0.003036165
edge_density(uni_wout_biz_net) # 0.1201957
[1] 0.1201957
dyadicity_uni_vs_biz <- edge_density(uni_wout_biz_net) / p_uni_vs_biz 
dyadicity_uni_vs_biz # 39.58799
[1] 39.58799
n_c # 54
[1] 54
p_uni_vs_biz # 0.003036165
[1] 0.003036165
n_nc_biz <- sum( V(net)$type == 'Business Enterprise' )
n_nc_biz # 1010
[1] 1010
exp_hetero_uni_vs_biz <- n_nc_biz * n_c * p_uni_vs_biz
exp_hetero_uni_vs_biz # 165.5925
[1] 165.5925
biz <- V(net)[which( V(net)$type == 'Business Enterprise' )]
biz <- names(biz)
# biz

m_mixed_vs_biz <- 0

for (row in 1:nrow(edges)) {
  from_obj <- edges[row, 'from']
  to_obj <- edges[row, 'to']
  
  if ( (from_obj %in% unis) && (to_obj %in% biz) ) {
    m_mixed_vs_biz <- m_mixed_vs_biz + 1
  }
  if ( (from_obj %in% biz) && (to_obj %in% unis) ) {
    m_mixed_vs_biz <- m_mixed_vs_biz + 1
  }
}

m_mixed_vs_biz # 1139
[1] 1139
heterophilicity_uni_vs_biz <- m_mixed_vs_biz / exp_hetero_uni_vs_biz
heterophilicity_uni_vs_biz # 6.878333
[1] 6.878333

Higher Education vs Government

uni_gov_net <- induced_subgraph( 
  net, 
  v=V(net)[which( V(net)$type %in% c('Higher Education', 'Government') )] 
)
# V(uni_gov_net)$type

uni_wout_gov_net <- induced_subgraph( 
  uni_gov_net, 
  v=V(uni_gov_net)[which( V(uni_gov_net)$type == 'Higher Education' )] 
)
# V(uni_wout_gov_net)$type


p_uni_vs_gov <- edge_density(uni_gov_net) 
p_uni_vs_gov # 0.04231381
[1] 0.04231381
edge_density(uni_wout_gov_net) # 0.1201957
[1] 0.1201957
dyadicity_uni_vs_gov <- edge_density(uni_wout_gov_net) / p_uni_vs_gov 
dyadicity_uni_vs_gov # 2.840578
[1] 2.840578
n_c # 54
[1] 54
p_uni_vs_gov # 0.04231381
[1] 0.04231381
n_nc_gov <- sum( V(net)$type == 'Business Enterprise' )
n_nc_gov # 1010
[1] 1010
exp_hetero_uni_vs_gov <- n_nc_gov * n_c * p_uni_vs_gov
exp_hetero_uni_vs_gov # 2307.795
[1] 2307.795
gov <- V(net)[which( V(net)$type == 'Business Enterprise' )]
gov <- names(gov)
# gov

m_mixed_vs_gov <- 0

for (row in 1:nrow(edges)) {
  from_obj <- edges[row, 'from']
  to_obj <- edges[row, 'to']
  
  if ( (from_obj %in% unis) && (to_obj %in% gov) ) {
    m_mixed_vs_gov <- m_mixed_vs_gov + 1
  }
  if ( (from_obj %in% gov) && (to_obj %in% unis) ) {
    m_mixed_vs_gov <- m_mixed_vs_gov + 1
  }
}

m_mixed_vs_gov # 0.4935447
[1] 1139
heterophilicity_uni_vs_gov <- m_mixed_vs_gov / exp_hetero_uni_vs_gov
heterophilicity_uni_vs_gov # 0.4935447
[1] 0.4935447

Соберем полученные значения dyadicity и heterophilicity вместе: - Higher Education vs все остальные: - dyadicity: 32.0898241 - heterophilicity: 6.9597056 - Higher Education vs Business Enterprise: - dyadicity: 39.5879866 - heterophilicity: 6.8783329 - Higher Education vs Government: - dyadicity: 2.840578 - heterophilicity: 0.4935447.

Мы видим, что dyadicity университетов при разделении на университеты и всех остальных (а также при разделении на университеты и бизнес) очень высокая. При этом heterophilicity также доволльно сильно превышает 1.

В чем может быть объяснение этой особенности данных? Как утверждается в статье “Functional dyadicity and heterophilicity of gene-gene interactions in statistical epistasis networks”, описанный выше факт может быть связан с тем, что вершины со значением метки 1 имеют большую центральность \(\Rightarrow\) хорошо связаны друг с другом и с вершинами другого типа.

В Задании 6 мы будем проверять гипотезу касательно высоких степеней вершин типа Higher Education среди крупных университетов.

Выводы

Выводы по Заданию 4: Мы получили, что несмотря на плотные связи учреждений высшего образования между собой, по крайней мере некоторые из них имеют также прочные связи с другими типами организаций (в частности с бизнесом).


Задание 5

Проведем процедуру кластеризации вершин при помощи Edge-betweenness и Fast-greedy методов и сравним полученные результаты с существующей классификацией.

Т.к. считать кратчайший путь для исходных весов ребер является не очень осмысленным, используем обратные для исходных веса ребер.

Замечание: Для Fast-greedy не важно, какие данные использовать: исходные или инвертированные, т.к. этот метод не учитывает веса ребер (только их количество).

# проводим кластеризацию при помощи метода Edge-betweenness
ceb <- cluster_edge_betweenness(net, weights=E(net)$weight)
Предупреждение: At core/community/edge_betweenness.c:493 : Membership vector will be selected based on the highest modularity score.
# смотрим на полученные в результате кластеризации объекты
mbship_ceb <- membership(ceb) 
# mbship_ceb

s_ceb <- sizes(ceb)
s_ceb
Community sizes
  1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26 
 45 213 233 154 229 190  75  46 164  48  32   2   2   2   3  15   2   2   8   2   2   4   2   2   2   2 
 27  28  29  30  31  32  33  34  35  36  37  38 
  7   2   2   2   2   2   2   2   2   2   3   2 
ms_ceb <- modularity(ceb)
ms_ceb # 0.527262
[1] 0.527262
# ceb
# > s_ceb <- sizes(ceb)
# > s_ceb
# Community sizes
#   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20 
#  45 213 233 154 229 190  75  46 164  48  32   2   2   2   3  15   2   2   8   2 
#  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36  37  38 
#   2   4   2   2   2   2   7   2   2   2   2   2   2   2   2   2   3   2 
# > ms_ceb <- modularity(ceb)
# > ms_ceb
# [1] 0.527262

Визуализация кластеризации методом Edge-betweenness:

plot(
  ceb, net, 
  vertex.label=NA, 
  vertex.color=V(net)$color, 
  layout=layout_nicely
)

plot(
  ceb, net, 
  vertex.label=NA, 
  vertex.color=V(net)$color, 
  layout=layout_with_lgl
)

Сравним результаты кластеризации Edge-betweenness и имеющуюся классификацию вершин:

compare(ceb, V(net)$type, method='nmi') # 
[1] 0.03399001
# здесь и далее мы используем нормализованное значение функции compare() для облегчения интерпретации возвращаемого результата

Таким образом, мы видим, что имеющаяся классификация вершин совсем не похожа на то, что мы получили при кластеризации. По всей видимости, “разделение по бутылочному горлышку” является не очень хорошим способом для кластеризации вершин в нашем датасете.

# проводим кластеризацию при помощи метода Fast-greedy
cfg <- cluster_fast_greedy(net, weights=E(net)$weight) 

# смотрим на полученные в результате кластеризации объекты
mbship_cfg <- membership(cfg) 
# mbship_cfg

s_cfg <- sizes(cfg)
s_cfg
Community sizes
  1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26 
219 144 212 132 141  94 189 120  84  82  28   3   2  15   3   3   2   2   2   2   2   2   2   2   2   2 
 27  28  29  30  31  32  33  34  35  36 
  2   2   2   2   2   2   2   2   2   2 
ms_cfg <- modularity(cfg)
ms_cfg # 0.5310055
[1] 0.5310055
# cfg
# > s_cfg <- sizes(cfg)
# > s_cfg
# Community sizes
#   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26 
# 219 144 212 132 141  94 189 120  84  82  28   3   2  15   3   3   2   2   2   2   2   2   2   2   2   2 
#  27  28  29  30  31  32  33  34  35  36 
#   2   2   2   2   2   2   2   2   2   2 
# > ms_cfg <- modularity(cfg)
# > ms_cfg
# [1] 0.5310055

Визуализация кластеризации методом Fast-greedy:

plot(
  cfg, net, 
  vertex.label=NA, 
  vertex.color=V(net)$color, 
  layout=layout_nicely
)

plot(
  cfg, net, 
  vertex.label=NA, 
  vertex.color=V(net)$color, 
  layout=layout_with_lgl
)

compare(cfg, V(net)$type, method='nmi') # 0.03386511
[1] 0.03386511

Таким образом, мы видим, что так же, как и предыдущий способ кластеризации, Fast-greedy не очень хорошо соответствует реальной классификации рассматриваемых институтов.

Выводы

Вывод по Заданию 5: Известные нам способы кластеризации (Edge-betweenness и Fast-greedy) не дали результата, похожего на имеющуюся в датасете классификацию.


Задание 6

Изначально был поставлен исследовательский вопрос, насколько активно при написании научных работ университеты Новой Зеландии взаимодействуют с другими типами организаций, нужно ли им как-то в этом способстовать извне (например, создавать общие лаботарии с индустриальными корпорациями и государственными органами). Помимо расчета значений гомофилии и различных видов центральностей, для ответа на заданный вопрос нам может помочь модель предсказания класса вершин Relational Neighbors Classifier (RNC).

Разделим все вершины на 2 класса: “1” - университет, “0” - иначе. Отберем из каждого класса по 10 вершин и положим вероятности их принадлежности первому классу соответственно 1 и 0. Для всех остальных вершин (unknown) положим эту вероятность равной 0.5. При каждой итерации будем обновлять вероятности каждой вершины исходя из вероятностей её соседей. В итоге, после 10 таких итераций получим для каждой вершины вероятность её принадлежности классу “1”, и отберем те вершины, чья вероятность больше порога 0.5 в качестве принадлежащих классу “1”.

Для избежания случайности повторим этот алгоритм 100 раз и построим гистограмму распределения числа предсказанных университетов, а также гистограмму распределения средних вероятностей принадлежности группе университетов.

res <- rep(NA, 20)
pr <- rep(NA, 20)

for (j in 1:20){ 
  network <- net
  V(network)[which( V(network)$type == 'Higher Education' )]$type = 1
  V(network)[which(V(network)$type != 1)]$type = 0
  
  
  # вероятность вершины перейти в класс churn = 1 равна доле соседей churn = 1 от общего числа соседей
  # используем матричные вычисления
  random_uni <- sample( V(network)[ which(V(network)$type == 1) ], 10 )
  random_not_uni <- sample( V(network)[ which(V(network)$type == 0) ], 10 )
  
  
  for (i in 1:1511){
    if (!(V(network)[i] %in% random_uni | (V(network)[i] %in% random_not_uni))){
      V(network)$type[i] = 0.5
    }
  }
  
  UniProb <-  as.numeric(V(network)$type)
  threshold <- 0.5
  A <- as_adjacency_matrix(network)
  A <- as.matrix(A)
  Neighbors <- rowSums(A) # общее число соседей вершины
  
  UniProb_iter <- UniProb
  for(i in 1:10){
    UniProb_iter <- as.vector((A %*% UniProb_iter) / Neighbors)
  }
  res[j] <- length(which(UniProb_iter > threshold))
  pr[j] <- mean(UniProb_iter)
}
hist(res, main='Число предсказанных университетов')

hist(pr, main='Средняя вероятность принадлежности классу 1')

Как можно увидеть, почти во всех случаях абсолютное число вершин предсказанj в качестве университетов. Получаем, что какие бы 10 университетов мы ни взяли, их класс дойдет до большинства вершин быстрее, чем противоположный класс 10 случайных вершин. Это распространяется и на случай, когда были выбраны наименее центральные университеты. Если бы университеты были плохо связаны с организациями другого типа, то их класс намного слабее распространялся бы на вершины другого типа, а это не так.

Значит, по крайней мере какие-то университеты (а именно наиболее центральные) довольно активно кооперируются с другими организациями (как, например, это делает Оклендский университет). Поэтому для таких университетов нет необходимости строить совместные с бизнесом и государством научные центры.

Вспомним про высокий показатель dyadicity у ВУЗов: выходит, что он получается таким большим из-за высокой гомофилии более мелких учебных заведений. Тогда можно предположить, что именно они плохо взаимодействуют с бизнесом и гос. органами.


Заключение

Как тогда можно им помочь? При моделировании их класс распространялся по сети через их соседей — крупные университеты. В таком случае, более разумно строить научные центры именно соединяющие мелкие университеты с крупными. Данным образом, казалось бы, усиливая гомофилию, мы, наоборот, будем способстовать развитию научных отношений университетов с индустриальными партнерами.

Замечание

Здесь мы предполагаем эталонность крупных университетов (например, Оклендского) с точки зрения эффективности взаимодействия, а также качества и количества научных работ, что продемонстрировано, например, в этой статье.

LS0tCnRpdGxlOiAi0JTQtyDQv9C+INCh0LXRgtC10LLRi9C8INC80L7QtNC10LvRj9C8IgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdAogIGF1dGhvcjogItCa0LDQsdCw0L3QvtCyINCY0LvRjNGPLCDQodGD0YXQvtCyINCQ0LvQtdC60YHQsNC90LTRgCwg0KHRi9GB0L7QtdCyINCd0LjQutC40YLQsCIKICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQKLS0tCgojIyDQn9C+0LTQs9C+0YLQvtCy0LjRgtC10LvRjNC90YvQtSDRiNCw0LPQuAoKYGBge3J9CiMg0KPRgdGC0LDQvdC+0LLQuNC8INGA0LDQsdC+0YfRg9GOINC00LjRgNC10LrRgtC+0YDQuNGOCnNldHdkKCJ+L0RvY3VtZW50cy9HaXRIdWIvUlByb2plY3RzX0VGL05ldHdvcmtzIikKYGBgCgpgYGB7ciwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KIyDQn9C+0LTQs9GA0YPQt9C40Lwg0L3QtdC+0LHRhdC+0LTQuNC80YvQtSDQtNC70Y8g0LTQsNC70YzQvdC10LnRiNC10LPQviDQsNC90LDQu9C40LfQsCDQsdC40LHQu9C40L7RgtC10LrQuAojIyBpbnN0YWxsLnBhY2thZ2VzKCJpZ3JhcGgiKQojIyBpbnN0YWxsLnBhY2thZ2VzKCJpZ3JhcGhkYXRhIikKIyMgaW5zdGFsbC5wYWNrYWdlcygiZ2dyYXBoIikKIyMgaW5zdGFsbC5wYWNrYWdlcygidGlkeWdyYXBoIikKIyMgaW5zdGFsbC5wYWNrYWdlcygiRGVzY1Rvb2xzIikKCgpsaWJyYXJ5KGlncmFwaCk7CmxpYnJhcnkoaWdyYXBoZGF0YSk7CmxpYnJhcnkoZ2dyYXBoKTsKbGlicmFyeSh0aWR5Z3JhcGgpOwpsaWJyYXJ5KERlc2NUb29scyk7CmBgYAoKIyMg0J7QsdGA0LDQsdC+0YLQutCwINC00LDQvdC90YvRhSDQuCDRgdC+0LfQtNCw0L3QuNC1INCz0YDQsNGE0LAKCmBgYHtyfQojINCX0LDQs9GA0YPQt9C40Lwg0LTQsNC90L3Ri9C1INC00LvRjyDQuNGB0YHQu9C10LTQvtCy0LDQvdC40Y86INC90LDQsdC+0YAg0YDQtdCx0LXRgCDQuCDQstC10YDRiNC40L0KZWRnZXMgPC0gcmVhZC5jc3YoImVkZ2VzXzEuY3N2IiwgaGVhZGVyPVQpIApjb2xuYW1lcyhlZGdlcykgPC0gYygnZnJvbScsICd0bycsICd0eXBlMScsICd0eXBlMicsICd3ZWlnaHQnKQoKbm9kZXMgPC0gdW5pcXVlKGVkZ2VzW2MoJ2Zyb20nLCAndHlwZTEnKV0pCm1vcmVfbm9kZXMgPC0gdW5pcXVlKGVkZ2VzW2MoJ3RvJywgJ3R5cGUyJyldKQoKY29sbmFtZXMobm9kZXMpIDwtIGMoJ29yZ2FuaXNhdGlvbicsICd0eXBlJykKY29sbmFtZXMobW9yZV9ub2RlcykgPC0gYygnb3JnYW5pc2F0aW9uJywgJ3R5cGUnKQoKbm9kZXMgPC0gcmJpbmQobm9kZXMsIG1vcmVfbm9kZXMpCm5vZGVzIDwtIHVuaXF1ZShub2Rlc1tjKCdvcmdhbmlzYXRpb24nLCAndHlwZScpXSkKcm93bmFtZXMobm9kZXMpIDwtIE5VTEwKZWRnZXMgPC0gZWRnZXNbYygnZnJvbScsICd0bycsICd3ZWlnaHQnKV0KCiMg0KHQvtC30LTQsNC00LjQvCDRgtCw0LrQttC1INC90LDQsdC+0YAg0L7QsdGA0LDRgtC90YvRhSDQstC10LvQuNGH0LjQvSDQtNC70Y8g0LLQtdGB0L7QsiDRgNC10LHQtdGAICjRjdGC0L4g0L/RgNC40LPQvtC00LjRgtGB0Y8g0L3QsNC8INCyINC00LDQu9GM0L3QtdC50YjQtdC8KS4g0JjRgdGF0L7QtNC90YvQtSDQstC10YHQsCDQvdCw0Lwg0YPQttC1INC90LUg0L/QvtC90LDQtNC+0LHRj9GC0YHRjwplZGdlcyR3ZWlnaHQgPC0gMSAvIGVkZ2VzJHdlaWdodAoKbmV0IDwtIGdyYXBoX2Zyb21fZGF0YV9mcmFtZShkPWVkZ2VzLCB2ZXJ0aWNlcz1ub2RlcywgZGlyZWN0ZWQ9RikKClYobmV0KSRjb2xvciA8LSBpZmVsc2UoIFYobmV0KSR0eXBlPT0iQnVzaW5lc3MgRW50ZXJwcmlzZSIsICJyZWQiLCAKICBpZmVsc2UoIFYobmV0KSR0eXBlPT0iUHJpdmF0ZSBub3QgZm9yIHByb2ZpdCIsICJwdXJwbGUiLCAKICAgIGlmZWxzZSggVihuZXQpJHR5cGU9PSJHb3Zlcm5tZW50IiwgImdyZWVuIiwgCiAgICAgIGlmZWxzZSggVihuZXQpJHR5cGU9PSJIaWdoZXIgRWR1Y2F0aW9uIiwgImJsdWUiLCAiYmxhY2siKSAKICAgICkgCiAgKSAKKQpoZWFkKFYobmV0KSRjb2xvciwgMTApCmBgYAoKKirQn9C+0Y/RgdC90LjQvCwg0L/QvtGH0LXQvNGDINCyINC00LDQu9GM0L3QtdC50YjQtdC8INCx0YPQtNC10Lwg0YDQsNCx0L7RgtCw0YLRjCDQuNC80LXQvdC90L4g0YEg0L7QsdGA0LDRgtC90YvQvNC4INCy0LXRgdCw0LzQuDoqKiDQmtGA0LDRgtGH0LDQudGI0LjQuSDQv9GD0YLRjCDQuCDQutGA0LDRgtGH0LDQudGI0LXQtSDRgNCw0YHRgdGC0L7Rj9C90LjQtSDQsiDQtNCw0L3QvdC+0Lkg0LfQsNC00LDRh9C1INCx0YPQtNGD0YIg0L/RgNC10LTRgdGC0LDQstC70Y/RgtGMINGB0L7QsdC+0Lkg0L3QtSDRgtC+INC20LUg0YHQsNC80L7QtSwg0YfRgtC+INC4INCyINC30LDQtNCw0YfQtSDRgSDQuNC30LTQtdGA0LbQutCw0LzQuCDQv9C10YDQtdCy0L7Qt9C+0Log0LjQu9C4INC00LvQuNC90LDQvNC4INGA0LDRgdGB0YLQvtGP0L3QuNC5INC80LXQttC00YMg0LLQtdGA0YjQuNC90LDQvNC4INCyINC60LDRh9C10YHRgtCy0LUg0LLQtdGB0L7QsiDRgNC10LHQtdGALiDQntGC0YDQuNGG0LDRgtC10LvRjNC90YvQtSDQstC10YHQsCDQvNGLINC90LUg0LjRgdC/0L7Qu9GM0LfRg9C10LwsINC/0L7RgtC+0LzRgyDRh9GC0L4gKtCw0LvQs9C+0YDQuNGC0Lwg0JTQtdC50LrRgdGC0YDRiyog0YDQsNCx0L7RgtCw0LXRgiDRgSDQvdC10L7RgtGA0LjRhtCw0YLQtdC70YzQvdGL0LzQuCDQstC10YHQsNC80Lgg0YDQtdCx0LXRgCwg0L/QvtGN0YLQvtC80YMg0LTQsNC70LXQtSDQvNGLINC+0L/QtdGA0LjRgNGD0LXQvCDRgSDQvtCx0YDQsNGC0L3Ri9C80Lgg0LLQtdGB0LDQvNC4LCDRgi7Qui4sINC90LAg0L3QsNGIINCy0LfQs9C70Y/QtCwg0Y3RgtC+0YIg0LLRi9Cx0L7RgCDRj9Cy0LvRj9C10YLRgdGPINC90LDQuNCx0L7Qu9C10LUg0L7Qv9GC0LjQvNCw0LvRjNC90YvQvCDQtNC70Y8g0L/RgNC10L7QtNC+0LvQtdC90LjRjyDQstC+0LfQvdC40LrRiNC40YUg0YLRgNGD0LTQvdC+0YHRgtC10LkuCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjINCY0YHRgdC70LXQtNC+0LLQsNGC0LXQu9GM0YHQutC40Lkg0LLQvtC/0YDQvtGBCgoqKtCY0YHRgdC70LXQtNC+0LLQsNGC0LXQu9GM0YHQutC40Lkg0LLQvtC/0YDQvtGBOioqINCa0LDQutC40LUg0LXRgdGC0Ywg0YHQv9C+0YHQvtCx0Ysg0YPQu9GD0YfRiNC10L3QuNGPINCy0LfQsNC40LzQvtC00LXQudGB0YLQstC40Y8g0YPRh9GA0LXQttC00LXQvdC40Lkg0LLRi9GB0YjQtdCz0L4g0L7QsdGA0LDQt9C+0LLQsNC90LjRjyDQndC+0LLQvtC5INCX0LXQu9Cw0L3QtNC40LggKNC10YHQu9C4INGN0YLQviDQstC+0L7QsdGJ0LUg0YLRgNC10LHRg9C10YLRgdGPKT8KCtCd0LDRiNC1INC40YHRgdC70LXQtNC+0LLQsNC90LjQtSDQv9C+0LrQsNC30YvQstCw0LXRgiwg0YfRgtC+INCy0L7Qt9C80L7QttC90L4g0L/QvtCy0YvRgdC40YLRjCDRjdGE0YTQtdC60YLQuNCy0L3QvtGB0YLRjCDQvdC10LHQvtC70YzRiNC40YUg0YPQvdC40LLQtdGA0YHQuNGC0LXRgtC+0LIg0L/QvtGB0YDQtdC00YHRgtCy0L7QvCDRg9Cy0LXQu9C40YfQtdC90LjRjyDRgdC+0YLRgNGD0LTQvdC40YfQtdGB0YLQstCwINGBINC60YDRg9C/0L3Ri9C80LgsINC60L7RgtC+0YDRi9C1INCyINGB0LLQvtGOINC+0YfQtdGA0LXQtNGMINC40LzQtdGO0YIg0YLQtdGB0L3QvtC1INGB0L7RgtGA0LXQtNC90LjRh9C10YHRgtCy0L4g0YEg0LHQuNC30L3QtdGB0L7QvC4KCtCU0LXRgtCw0LvQuCDRgdC8LiDQsiAq0JfQsNC00LDQvdC40LggNiouCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjINCQ0L3QsNC70LjQtyDQtNCw0YLQsNGB0LXRgtCwCgojIyMg0J7Qv9C40YHQsNC90LjQtSDQtNCw0YLQsNGB0LXRgtCwCgrQlNCw0YLQsNGB0LXRgiDQv9GA0LXQtNGB0YLQsNCy0LvRj9C10YIg0LjQtyDRgdC10LHRjyDQvNC90L7QttC10YHRgtCy0L4g0LLQtdGA0YjQuNC9INGBINC60LDRh9C10YHRgtCy0LXQvdC90YvQvNC4INGF0LDRgNCw0LrRgtC10YDQuNGB0YLQuNC60LDQvNC4INC4INC80L3QvtC20LXRgdGC0LLQviDRgNC10LHQtdGAINGBINGH0LjRgdC70L7QstGL0LzQuCDRhdCw0YDQsNC60YLQtdGA0LjRgdGC0LjQutCw0LzQuCAo0LLQtdGB0LDQvNC4KS4KCtCS0LXRgNGI0LjQvdCw0LzQuCDRj9Cy0LvRj9GO0YLRgdGPINC+0YDQs9Cw0L3QuNC30LDRhtC40Lgg0J3QvtCy0L7QuSDQl9C10LvQsNC90LTQuNC4LCDQutC+0YLQvtGA0YvQtSDQt9Cw0L3QuNC80LDRjtGC0YHRjyDQvdCw0L/QuNGB0LDQvdC40LXQvCDQvdCw0YPRh9C90YvRhSDRgdGC0LDRgtC10Lkg0LIg0LrQsNGH0LXRgdGC0LLQtSDQvtC00L3QvtCz0L4g0LjQtyDQstC40LTQvtCyINC00LXRj9GC0LXQu9GM0L3QvtGB0YLQuC4g0JrQsNGH0LXRgdGC0LLQtdC90L3QvtC5INGF0LDRgNCw0LrRgtC10YDQuNGB0YLQuNC60L7QuSDQstC10YDRiNC40L0g0Y/QstC70Y/QtdGC0YHRjyDQstC40LQg0L7RgNCz0LDQvdC40LfQsNGG0LjQuCAo0LPQvtGB0YPQtNCw0YDRgdGC0LLQtdC90L3QsNGPINC+0YDQs9Cw0L3QuNC30LDRhtC40LgsINCy0YvRgdGI0LXQtSDRg9GH0LXQsdC90L7QtSDQt9Cw0LLQtdC00LXQvdC40LUsINC60L7QvNC80LXRgNGH0LXRgdC60L7QtSDQv9GA0LXQtNC/0YDQuNGP0YLQuNC1INC4INGH0LDRgdGC0L3QvtC1INC90LXQutC+0LzQvNC10YDRh9C10YHQutC+0LUg0L/RgNC10LTQv9GA0LjRj9GC0LjQtSkuINCS0YHQtdCz0L4g0LIg0LTQsNGC0LDRgdC10YLQtSAxNTExINCy0LXRgNGI0LjQvS4KCtCc0LXQttC00YMgYGlgLdC+0Lkg0LggYGpgLdC+0Lkg0LLQtdGA0YjQuNC90LDQvNC4ICjQvtGA0LPQsNC90LjQt9Cw0YbQuNGP0LzQuCkg0YHRg9GJ0LXRgdGC0LLRg9C10YIg0YDQtdCx0YDQviwg0LXRgdC70Lgg0LfQsCDQv9C10YDQuNC+0LQgMjAxMC0yMDE1INCz0LMuINC90LAgU2NvcHVzINCx0YvQu9CwINC+0L/Rg9Cx0LvQuNC60L7QstCw0L3QsCDRhdC+0YLRjyDQsdGLINC+0LTQvdCwINGB0YLQsNGC0YzRjywg0YXQvtGC0Y8g0LHRiyDQvtC00LjQvSDQsNCy0YLQvtGAINC60L7RgtC+0YDQvtC5INGH0LjRgdC70LjRgtGB0Y8g0LIg0L7RgNCz0LDQvdC40LfQsNGG0LjQuCBgaWAsINCwINC00YDRg9Cz0L7QuSDQsNCy0YLQvtGAIC0tINCyINC+0YDQs9Cw0L3QuNC30LDRhtC40LggYGpgLiDQktGB0LXQs9C+INCyINC00LDRgtCw0YHQtdGC0LUgNDI3MyDRgNC10LHRgNCwLgoK0JLQtdGBINGA0LXQsdGA0LAg0YDQsNCy0LXQvSDQutC+0LvQuNGH0LXRgdGC0LLRgyDRgdC+0LLQvNC10YHRgtC90YvRhSDQvtC/0YPQsdC70LjQutC+0LLQsNC90L3Ri9GFINC90LDRg9GH0L3Ri9GFINGA0LDQsdC+0YIuINCV0YHQu9C4INCy0LXRgSDRgNC10LHRgNCwINC80LXQttC00YMgYGlgLdC+0Lkg0LggYGpgLdC+0Lkg0LLQtdGA0YjQuNC90L7QuSDRgNCw0LLQtdC9IDMsINGC0L4g0Y3RgtC+INC+0LfQvdCw0YfQsNC10YIsINGH0YLQviDQt9CwINGD0LrQsNC30LDQvdC90YvQuSDQv9C10YDQuNC+0LQg0L3QsCBTY29wdXMg0LHRi9C70L4g0L7Qv9GD0LHQu9C40LrQvtCy0LDQvdC+IDMg0L3QsNGD0YfQvdGL0LUg0YDQsNCx0L7RgtGLLCDRgyDQutC+0YLQvtGA0YvRhSDRhdC+0YLRjyDQsdGLINC+0LTQuNC9INCw0LLRgtC+0YAg0YfQuNGB0LvQuNGC0YHRjyDQsiDQvtGA0LPQsNC90LjQt9Cw0YbQuNC4IGBpYCwg0LAg0LTRgNGD0LPQvtC5IC0tLSDQsiDQvtGA0LPQsNC90LjQt9Cw0YbQuNC4IGBqYC4KCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMjINCX0LDQtNCw0L3QuNC1IDIKCtCf0YDQuCDQuNGB0L/QvtC70YzQt9C+0LLQsNC90LjQuCDQvdC10YHQutC+0LvRjNC60LjRhSDQv9Cw0LrQtdGC0L7QsiDQtNC70Y8g0YDQsNCx0L7RgtGLINGBINCz0YDQsNGE0LDQvNC4INC90LUg0L7QutCw0LfQsNC70L7RgdGMINCy0L7Qt9C80L7QttC90YvQvCDQuNC90YLQtdGA0L/RgNC10YLQuNGA0YPQtdC80L4g0LLQuNC30YPQsNC70LjQt9C40YDQvtCy0LDRgtGMINCz0YDQsNGEINC/0L7Qu9C90L7RgdGC0YzRji4g0J/QvtGN0YLQvtC80YMg0LTQu9GPINC+0YLQvtCx0YDQsNC20LXQvdC40Y8g0YHRgtGA0YPQutGC0YPRgNGLINC90LDRiNC10Lkg0YHQtdGC0Lgg0L3QsNC50LTQtdC8IDEwMCDRgdCw0LzRi9GFINGG0LXQvdGC0YDQsNC70YzQvdGL0YUg0L/QviDRgdGC0LXQv9C10L3QuCDQstC10YDRiNC40L0g0Lgg0L/RgNC10LTRgdGC0LDQstC40Lwg0YHQstGP0LfQuCDQvNC10LbQtNGDINC90LjQvNC4INC/0YDQuCDQv9C+0LzQvtGJ0Lgg0L/QsNC60LXRgtCwIGBnZ3JhcGhgLgoKYGBge3J9ClYobmV0KSRkZWdyZWVzIDwtIGRlZ3JlZShuZXQpCm5vZGVzJGRlZ3JlZXMgPC0gVihuZXQpJGRlZ3JlZXMKCmZvcl92aXNfbiA8LSBub2Rlc1tvcmRlcigtbm9kZXMkZGVncmVlcyksXVsxOjEwMCwgMToyXQpmb3JfdmlzX2UgPC0gZWRnZXNbKGVkZ2VzJGZyb20gJWluJSBmb3JfdmlzX24kb3JnYW5pc2F0aW9uICYgZWRnZXMkdG8gJWluJSBmb3JfdmlzX24kb3JnYW5pc2F0aW9uKSxdCgpmb3JfdmlzX25ldCA8LSBncmFwaF9mcm9tX2RhdGFfZnJhbWUoZD1mb3JfdmlzX2UsIHZlcnRpY2VzPWZvcl92aXNfbiwgZGlyZWN0ZWQ9RikKVihmb3JfdmlzX25ldCkkZGVncmVlcyA8LSBkZWdyZWUoZm9yX3Zpc19uZXQpCgpmb3JfdmlzX25ldCAlPiUKICBnZ3JhcGgobGF5b3V0PSdncmFwaG9wdCcpICsKICBnZW9tX25vZGVfcG9pbnQoYWVzKGNvbG9yID0gdHlwZSwgc2l6ZT1yb3VuZChkZWdyZWVzLzIwKSkpICsKICBnZW9tX2VkZ2VfbGluayhhbHBoYSA9IDAuMDUpICsKICB0aGVtZV92b2lkKCkgKwogIGdndGl0bGUoIk5ldHdvcmsgb2YgTmV3IFplYWxhbmQgb3JnYW5pc2F0aW9ucyIpCmBgYAoK0JrQsNC6INC80L7QttC90L4g0YPQstC40LTQtdGC0YwsINGB0YDQtdC00LggMTAwINGB0LDQvNGL0YUg0YbQtdC90YLRgNCw0LvRjNC90YvRhSDQstC10YDRiNC40L0g0YEg0LrQvtC70LjRh9C10YHRgtCy0LXQvdC90L7QuSDRgtC+0YfQutC4INC30YDQtdC90LjRjyDQv9GA0LXQvtCx0LvQsNC00LDRjtGCINC+0YDQs9Cw0L3QuNC30LDRhtC40Lgg0LPQvtGB0YPQtNCw0YDRgdGC0LLQtdC90L3QvtCz0L4g0YHQtdC60YLQvtGA0LAsINC+0LTQvdCw0LrQviDRgdCw0LzRi9C80Lgg0LrRgNGD0L/QvdGL0LzQuCDQt9C00LXRgdGMINGP0LLQu9GP0Y7RgtGB0Y8g0L3QvtCy0L7Qt9C10LvQsNC90LTRgdC60LjQtSDRg9C90LjQstC10YDRgdC40YLQtdGC0YsuINCf0LXRgNCy0YvQtSA1INC80LXRgdGCINC/0L4g0YfQuNGB0LvRgyDRgdC+0LLQvNC10YHRgtC90YvRhSDQvdCw0YPRh9C90YvRhSDRgNCw0LHQvtGCINC/0YDQuNC90LDQtNC70LXQttCw0YIg0LjQvNC10L3QvdC+INC40LwsINC70LjQtNC10YDQvtC8INC/0L4g0LTQsNC90L3QvtC80YMg0L/QvtC60LDQt9Cw0YLQtdC70Y4g0Y/QstC70Y/QtdGC0YHRjyAq0KPQvdC40LLQtdGA0YHQuNGC0LXRgiDQntC60LvQtdC90LTQsCosINGB0LDQvNGL0Lkg0LrRgNGD0L/QvdGL0Lkg0Lgg0L/RgNC10YHRgtC40LbQvdGL0Lkg0YPQvdC40LLQtdGA0YHQuNGC0LXRgiDQndC+0LLQvtC5INCX0LXQu9Cw0L3QtNC40LguCgrQoNCw0YHRgdGH0LjRgtCw0LXQvCAqKtCx0LDQt9C+0LLRi9C1INC/0LDRgNCw0LzQtdGC0YDRiyoqINC90LDRiNC10LPQviDQs9GA0LDRhNCwLiDQotCw0Log0LrQsNC6INCy0LXRgdCw0LzQuCDQtNGD0LMg0LIg0LTQsNC90L3QvtC8INGB0LvRg9GH0LDQtSDRj9Cy0LvRj9C10YLRgdGPINGH0LjRgdC70L4g0YHQvtCy0LzQtdGB0YLQvdGL0YUg0YDQsNCx0L7Rgiwg0YLQviDQtdGB0YLRjCAi0YHQuNC70LAg0YHQstGP0LfQuCIg0LTQstGD0YUg0LLQtdGA0YjQuNC9LCDQsdGD0LTQtdC8INC40YHQv9C+0LvRjNC30L7QstCw0YLRjCDQvtCx0YDQsNGC0L3Ri9C1INCy0LXRgdCwINC00LvRjyDQv9C+0LTRgdGH0LXRgtCwINGG0LXQvdGC0YDQsNC70YzQvdC+0YHRgtC10Lkg0YfQtdGA0LXQtyDQutGA0LDRgtGH0LDQudGI0LjQtSDQv9GD0YLQuC4g0K3RgtC+INC00L7QstC+0LvRjNC90L4g0YDQsNC30YPQvNC90L4sINGC0LDQuiDQutCw0Log0L7RgiDQvdCw0L/QuNGB0LDQvdC40Y8g0LTQvtC/0L7Qu9C90LjRgtC10LvRjNC90L7QuSDQvtCx0YnQtdC5INGA0LDQsdC+0YLRiyDQv9GA0LjRgNC+0YHRgiDQsiDRgdC40LvQtSDRgdCy0Y/Qt9C4INC00LLRg9GFINC+0YDQs9Cw0L3QuNC30LDRhtC40Lkg0LTQvtC70LbQtdC9INC80L7QvdC+0YLQvtC90L3QviDRgdC90LjQttCw0YLRjNGB0Y8sINC60LDQuiDQuCDRgNCw0LfQvdC40YbQsCDQsiDQv9GD0YLQuCDQtNC+INGB0L7RgdC10LTQsC4KCmBgYHtyfQoj0KHRh9C40YLQsNC10Lwg0LHQsNC30L7QstGL0LUg0L/QsNGA0LDQvNC10YLRgNGLINCz0YDQsNGE0LAKCiMgRGVuc2l0eQojIFRoZSBwcm9wb3J0aW9uIG9mIHByZXNlbnQgZWRnZXMgZnJvbSBhbGwgcG9zc2libGUgdGllcy4KcCA8LSBlZGdlX2RlbnNpdHkobmV0KQoKIyDRgdCy0Y/Qt9C90L7RgdGC0Ywg0YHQtdGC0LgKbm8gPC0gaWdyYXBoOjpjb21wb25lbnRzKG5ldCkkbm8gIyDQsiDQv9Cw0LrQtdGC0LUgc3RhdG5ldCDRgtCw0LrQvtC1INC20LUg0L3QsNC30LLQsNC90LjQtQpjc2l6ZSA8LSBpZ3JhcGg6OmNvbXBvbmVudHMobmV0KSRjc2l6ZQpjc2l6ZQoKCiMgRGlhbWV0ZXIgKGxvbmdlc3QgZ2VvZGVzaWMgZGlzdGFuY2UpICjQtdGB0LvQuCDQvdC10YHQutC+0LvRjNC60L4g0LrQvtC80L/QvtC90LXQvdGCLCDRgtC+INC00LjQsNC80LXRgtGAINGB0LDQvNC+0Lkg0LHQvtC70YzRiNC+0LkpCiMgTm90ZSB0aGF0IGVkZ2Ugd2VpZ2h0cyBhcmUgdXNlZCBieSBkZWZhdWx0LCB1bmxlc3Mgc2V0IHRvIE5BLgpkaWFtIDwtIGRpYW1ldGVyKG5ldCwgd2VpZ2h0cz1OQSkKZGlhbV93IDwtIGRpYW1ldGVyKG5ldCkKcGF0aCA8LSBnZXRfZGlhbWV0ZXIobmV0LCB3ZWlnaHRzPU5BKQpwYXRoX3cgPC0gZ2V0X2RpYW1ldGVyKG5ldCkKcGF0aApwYXRoX3cKCiMg0YDQsNGB0YHRh9C40YLQsNC10Lwg0LrRgNCw0YLRh9Cw0LnRiNC40LUg0L/Rg9GC0LgKIyBBdmVyYWdlIHBhdGggbGVuZ3RoIAojIFRoZSBtZWFuIG9mIHRoZSBzaG9ydGVzdCBkaXN0YW5jZSBiZXR3ZWVuIGVhY2ggcGFpciBvZiBub2RlcyBpbiB0aGUgbmV0d29yayAKIyAoaW4gYm90aCBkaXJlY3Rpb25zIGZvciBkaXJlY3RlZCBncmFwaHMpLiAKbV9kaXN0IDwtIG1lYW5fZGlzdGFuY2UobmV0LCB3ZWlnaHRzPU5BKQptX2Rpc3RfdyA8LSBtZWFuX2Rpc3RhbmNlKG5ldCkKYGBgCgrQn9C70L7RgtC90L7RgdGC0Ywg0L3QsNGI0LXQs9C+INCz0YDQsNGE0LAg0YHQvtGB0YLQsNCy0LvRj9C10YIgYHIgcm91bmQocCwgNClgLiDQotCw0LrQsNGPINC90LjQt9C60LDRjyDQv9C70L7RgtC90L7RgdGC0YwgKNCy0LXRgNC+0Y/RgtC90L7RgdGC0Ywg0L7QsdGA0LDQt9C+0LLQsNC90LjRjyDRgdCy0Y/Qt9C4KSDQtNC+0LLQvtC70YzQvdC+INC10YHRgtC10YHRgtCy0LXQvdC90LDRjyDQtNC70Y8g0LLQtdGA0L7Rj9GC0L3QvtGB0YLQuCDQvdCw0L/QuNGB0LDQvdC40Y8g0L3QsNGD0YfQvdC+0Lkg0YDQsNCx0L7RgtGLLiDQndCw0YjQsCDRgdC10YLRjCDQuNC80LXQtdGCIGByIG5vYCDQutC+0LzQv9C+0L3QtdC90YIg0YHQstGP0LfQvdC+0YHRgtC4OiDQvtC00L3QsCDQs9C70LDQstC90LDRjywg0YHQvtC10LTQuNC90Y/RjtGJ0LDRjyDQv9GA0LDQutGC0LjRh9C10YHQutC4INCy0YHQtSDQstC10YDRiNC40L3Riywg0LAg0LLRgdC1INC+0YHRgtCw0LvRjNC90YvQtSDQuNC80LXRjtGCINC/0L4gMi0zINCy0LXRgNGI0LjQvdGLLiDQlNC40LDQvNC10YLRgCAo0L3QsNC40LHQvtC70YzRiNC40Lkg0LjQtyDQutGA0LDRgtGH0LDRiNC40YUg0L/Rg9GC0LXQuSkg0LjQvNC10LXRgiDQtNC70LjQvdGDIGByIHJvdW5kKGRpYW1fdywgMilgLCDQuNC70LggYHIgZGlhbWAsINC10YHQu9C4INCx0YDQsNGC0Ywg0LXQtNC40L3QuNGH0L3Ri9C1INCy0LXRgdCwINC00LvRjyDQstGB0LXRhSDQtNGD0LMuCgoqKtCY0LfRg9GH0LjQvCDRgdC+0YHQtdC00YHRgtCy0L4g0YHQsNC80L7QuSDRhtC10L3RgtGA0LDQu9GM0L3QvtC5INCy0LXRgNGI0LjQvdGLIC0tLSDQntC60LvQtdC90LTRgdC60L7Qs9C+INCj0L3QuNCy0LXRgNGB0LjRgtC10YLQsCoqICjRgSDQutC10Lwg0YfQsNGJ0LUg0LLRgdC10LPQviDQstC30LDQuNC80L7QtNC10LnRgdGC0LLRg9C10YIg0L3QsNC40LHQvtC70LXQtSDQv9GA0LXRgdGC0LjQttC90YvQuSDQktCj0Jcg0YHRgtGA0LDQvdGLKToKCmBgYHtyfQojIFdlIGNhbiBhbHNvIGVhc2lseSBpZGVudGlmeSB0aGUgaW1tZWRpYXRlIG5laWdoYm9ycyBvZiBhIHZlcnRleC4KIyBUaGUgJ25laWdoYm9ycycgZnVuY3Rpb24gZmluZHMgYWxsIG5vZGVzIG9uZSBzdGVwIG91dCBmcm9tIHRoZSBmb2NhbCBhY3Rvci4KIyBUbyBmaW5kIHRoZSBuZWlnaGJvcnMgZm9yIG11bHRpcGxlIG5vZGVzLCB1c2UgJ2FkamFjZW50X3ZlcnRpY2VzKCknLgpkIDwtIGRhdGEuZnJhbWUobmVpZ2hib3JzKG5ldCwgVihuZXQpWyJVbml2ZXJzaXR5IG9mIEF1Y2tsYW5kIl0sIG1vZGU9InRvdGFsIikkdHlwZSkKZ3JvdXBzIDwtIGFzLmRhdGEuZnJhbWUodGFibGUoZCkpWywgMl0KcGllKGdyb3VwcywgbGFiZWxzPXBhc3RlMChhcy5kYXRhLmZyYW1lKHRhYmxlKGQpKVssIDFdLCAnLCAnLHJvdW5kKGdyb3Vwcy9zdW0oZ3JvdXBzKSoxMDAsIGRpZ2l0cz0xKSwgJyUnKSwgCiAgICBjb2w9Yyg1LCAyLCAzLCA0KSwgbWFpbj0nTmVpZ2hib3JzIG9mIFVuaXZlcnNpdHkgb2YgQXVja2xhbmQnKQoKYGBgCgpgYGB7cn0KIyBUbyBmaW5kIG5vZGUgbmVpZ2hib3Job29kcyBnb2luZyBtb3JlIHRoYW4gb25lIHN0ZXAgb3V0LCB1c2UgZnVuY3Rpb24gJ2VnbygpJwojIHdpdGggcGFyYW1ldGVyICdvcmRlcicgc2V0IHRvIHRoZSBudW1iZXIgb2Ygc3RlcHMgb3V0IHRvIGdvIGZyb20gdGhlIGZvY2FsIG5vZGUocykuCm5laWdoMiA8LSBkYXRhLmZyYW1lKGVnbyhuZXQsIG9yZGVyID0gMiwgbm9kZXMgPSBWKG5ldClbIlVuaXZlcnNpdHkgb2YgQXVja2xhbmQiXSlbWzFdXSR0eXBlKQpncm91cHMyIDwtIGFzLmRhdGEuZnJhbWUodGFibGUobmVpZ2gyKSlbLCAyXQpwaWUoZ3JvdXBzMiwgbGFiZWxzPXBhc3RlMChhcy5kYXRhLmZyYW1lKHRhYmxlKG5laWdoMikpWywgMV0sICcsICcscm91bmQoZ3JvdXBzMi9zdW0oZ3JvdXBzMikqMTAwLCBkaWdpdHM9MSksICclJyksIAogICAgY29sPWMoNSwgMiwgMywgNCksIG1haW49J1R3by1zdGVwIG5laWdoYm9ycyBvZiBVbml2ZXJzaXR5IG9mIEF1Y2tsYW5kJykKYGBgCgrQlNC+0LLQvtC70YzQvdC+INC+0LbQuNC00LDQtdC80L4sINGH0YLQviDRh9Cw0YnQtSDQstGB0LXQs9C+INCyINC90LDQv9C40YHQsNC90LjQuCDQvdCw0YPRh9C90YvRhSDRgNCw0LHQvtGCINGC0LDQutC+0Lkg0YPRgdC/0LXRiNC90YvQuSDRg9C90LjQstC10YDRgdC40YLQtdGCINGB0L7RgtGA0YPQtNC90LjRh9Cw0LXRgiDRgSDQuNC90LTRg9GB0YLRgNC40LXQuS4gKirQrdGC0L4g0L/QvtC00YLQstC10LbQtNCw0LXRgiDQvdCw0YjQtSDQv9GA0LXQtNC/0L7Qu9C+0LbQtdC90LjQtSDQviDRgtC+0LwsINGD0YHQv9C10YUg0L3QsNGD0YfQvdC+0Lkg0YDQsNCx0L7RgtGLINC30LDQstC40YHQuNGCINC+0YIg0YDQsNCx0L7RgtGLINGBINCx0LjQt9C90LXRgdC+0LwuKiog0JIg0LHQu9C40LbQsNC50YjQtdC8INC+0LrRgNGD0LbQtdC90LjQuCDQtNCw0L3QvdC+0Lkg0L7RgNCz0LDQvdC40LfQsNGG0LjQuCDRgtCw0LrQttC1INC/0YDQuNC90Y/RgtC+INCy0LXRgdGC0Lgg0LjRgdGB0LvQtdC00L7QstCw0L3QuNGPINGBINC40L3QtNGD0YHRgtGA0LjQtdC5LgoKKirQodGA0LDQstC90LjQvCDQvdCw0YjRgyDRgdC10YLRjCDRgSDRgtC10L7RgNC40YLQuNGH0LXRgdC60LjQvNC4INC80L7QtNC10LvRj9C80Lgg0YHQu9GD0YfQsNC50L3QvtCz0L4g0LPRgNCw0YTQsCoqINC90LAg0L7RgdC90L7QstC1ICrRgNCw0YHQv9GA0LXQtNC10LvQtdC90LjRjyDRh9C40YHQu9CwINC40YUg0YHQvtGB0LXQtNC10LkqLCAq0LTQuNCw0LzQtdGC0YDQsCosINGBKtGA0LXQtNC90LXQs9C+INC60YDQsNGC0YfQsNC50YjQtdCz0L4g0L/Rg9GC0LgqINC4ICrRh9C40YHQu9CwINC60L7QvNC/0L7QvdC10L3RgiDRgdCy0Y/Qt9C90L7RgdGC0LgqLiDQndCw0YfQvdC10Lwg0YEg0LzQvtC00LXQu9C4INGB0LvRg9GH0LDQudC90L7Qs9C+INCz0YDQsNGE0LAgKtCt0YDQtNC10YjQsC3QoNC10L3RjNC4Ki4KCmBgYHtyfQoj0JPQtdC90LXRgNC40YDRg9C10Lwg0LzQvtC00LXQu9C4INGB0LvRg9GH0LDQudC90L7Qs9C+INCz0YDQsNGE0LAgZXJkb3MucmVueWkKcCA8LSBlZGdlX2RlbnNpdHkobmV0KQoKcmFuZG9tX21vZGVsIDwtIGVyZG9zLnJlbnlpLmdhbWUobj1nb3JkZXIobmV0KSwgcC5vci5tPXAsIHR5cGU9J2ducCcpCnBhcihtZnJvdyA9IGMoMSwgMikpCmhpc3QoZGVncmVlKG5ldCksIG1haW4gPSAiSGlzdG9ncmFtIG9mIG5vZGUgZGVncmVlIiwgYnJlYWtzID0gMTp2Y291bnQobmV0KS0xLCBwcm9iID0gVFJVRSwgeGxpbT1yYW5nZShjKDAsIDIwKSkpCmhpc3QoZGVncmVlKHJhbmRvbV9tb2RlbCksIG1haW4gPSAiSGlzdG9ncmFtIG9mIG5vZGUgZGVncmVlIiwgYnJlYWtzID0gMTp2Y291bnQobmV0KS0xLCBwcm9iID0gVFJVRSwgeGxpbT1yYW5nZShjKDAsIDIwKSkpCnBhcihtZnJvdyA9IGMoMSwgMSkpCgpnbCA8LSB2ZWN0b3IoJ2xpc3QnLCAxMDApCm0gPC0gcmVwKE5BLCAxMDApCmQgPC0gcmVwKE5BLCAxMDApCmEgPC0gcmVwKE5BLCAxMDApCmZvciAoaSBpbiAxOjEwMCl7CiAgZ2xbW2ldXSA8LSBlcmRvcy5yZW55aS5nYW1lKG49Z29yZGVyKG5ldCksIHAub3IubT1wLCB0eXBlPSdnbnAnKQogIG1baV0gPC0gbWVhbl9kaXN0YW5jZShnbFtbaV1dKQogIGRbaV0gPC0gZGlhbWV0ZXIoZ2xbW2ldXSkKICBhW2ldIDwtIGlncmFwaDo6Y29tcG9uZW50cyhnbFtbaV1dKSRubwp9Cm1lYW5fZGlzdGFuY2UgPC0gbQpoaXN0KG1lYW5fZGlzdGFuY2UsIHhsaW09cmFuZ2UoYyhtaW4obSwgbWVhbl9kaXN0YW5jZShuZXQpKSwgbWF4KG0sIG1lYW5fZGlzdGFuY2UobmV0KSkpKSkKYWJsaW5lKHY9bWVhbl9kaXN0YW5jZShuZXQpLCBjb2w9J3JlZCcsIGx0eT0zLCBsd2Q9MikgCgpkaWFtZXRlciA8LSBkCmhpc3QoZGlhbWV0ZXIsIHhsaW09cmFuZ2UoYyhtaW4oZCwgZGlhbWV0ZXIobmV0LCB3ZWlnaHRzPU5BKSksIG1heChkLCBkaWFtZXRlcihuZXQsIHdlaWdodHM9TkEpKSkpKQphYmxpbmUodj1kaWFtZXRlcihuZXQsIHdlaWdodHM9TkEpLCBjb2w9J3JlZCcsIGx0eT0zLCBsd2Q9MikgCgpudW1iZXJfb2ZfY29tcG9uZW50cyA8LSBhCmhpc3QobnVtYmVyX29mX2NvbXBvbmVudHMsIHhsaW09cmFuZ2UoYygwLCAyNSkpKQphYmxpbmUodj1pZ3JhcGg6OmNvbXBvbmVudHMobmV0KSRubywgY29sPSdyZWQnLCBsdHk9MywgbHdkPTIpCmBgYAoK0JrQsNC6INC80L7QttC90L4g0LfQsNC80LXRgtC40YLRjCwgKirQstGB0LUg0YDQsNGB0YHQvNCw0YLRgNC40LLQsNC10LzRi9C1INC/0L7QutCw0LfQsNGC0LXQu9C4INC90LDRiNC10Lkg0YHQtdGC0Lgg0LfQvdCw0YfQuNC80L4g0L7RgtC70LjRh9Cw0Y7RgtGB0Y8g0L7RgiDQvNC+0LTQtdC70YzQvdGL0YUqKiwg0LfQvdCw0YfQuNGCLCDRgdGC0YDRg9C60YLRg9GA0YMg0L3QsNGI0LXQuSDRgdC10YLQuCDQvdC10LvRjNC30Y8g0L7Qv9C40YHQsNGC0Ywg0LTQsNC90L3Ri9C8INC+0LHRgNCw0LfQvtC8LgoKKirQntCx0YDQsNGC0LjQvNGB0Y8g0Log0LzQvtC00LXQu9C4ICLQnNCw0LvQvtCz0L4g0LzQuNGA0LAiKiog0YEg0YDQtdCz0YPQu9GP0YDQvdC+0Lkg0YDQtdGI0LXRgtC60L7QuS4g0J7QtNC90LDQutC+INCyINGN0YLQvtC8INGB0LvRg9GH0LDQtSDRgdC/0LXRgNCy0LAg0L3Rg9C20L3QviDQv9C+0LTQvtCx0YDQsNGC0Ywg0LPQuNC/0LXRgNC/0LDRgNCw0LzQtdGC0YAgLS0tINC00L7Qu9GOINC/0LXRgNC10L/RgNC40YHQvtC10LTQuNC90LXQvdC90YvRhSDQtNGD0LMuCgpgYGB7cn0KI9CT0LXQvdC10YDQuNGA0YPQtdC8INC80L7QtNC10LvQuCDRgdC70YPRh9Cw0LnQvdC+0LPQviDQs9GA0LDRhNCwINGBINGA0LXQs9GD0LvRj9GA0L3QvtC5INGA0LXRiNC10YLQutC+0LkKbl9vZl9uZWkgPC0gbWVhbihkZWdyZWUobmV0KSkKZGlhbV9uZXQgPC0gZGlhbWV0ZXIobmV0LCB3ZWlnaHRzPU5BKQoj0JjRidC10Lwg0L7Qv9GC0LjQvNCw0LvRjNC90L7QtSDQt9C90LDRh9C10L3QuNC1IHAKbWVhbl9kaXN0X25ldCA8LSBtZWFuX2Rpc3RhbmNlKG5ldCkKbW9kZWwgPC0gdmVjdG9yKCdsaXN0JywgMTAwKQptIDwtIHJlcChOQSwgMTAwKQpkIDwtIHJlcChOQSwgMTAwKQpyZXMgPC0gcmVwKE5BLCAxMDApCmZvciAoaSBpbiAxOjEwMCl7CiAgbW9kZWxbW2ldXSA8LSBzYW1wbGVfc21hbGx3b3JsZChkaW0gPSAxLCBzaXplID0gZ29yZGVyKG5ldCksIG5laSA9IG5fb2ZfbmVpLCBwID0gaS8xMDApCiAgbVtpXSA8LSBtZWFuX2Rpc3RhbmNlKG1vZGVsW1tpXV0pCiAgZFtpXSA8LSBkaWFtZXRlcihtb2RlbFtbaV1dKQogIHJlc1tpXSA8LSAoKG1baV0tbWVhbl9kaXN0X25ldCleMisoZFtpXS1kaWFtX25ldCleMileKDEvMikgCn0KCiMgcCA9IDAuOTkKCnJhbmRvbV9tb2RlbCA8LSBzYW1wbGVfc21hbGx3b3JsZChkaW0gPSAxLCBzaXplID0gZ29yZGVyKG5ldCksIG5laSA9IG5fb2ZfbmVpLCBwID0gMC45OSkKcGFyKG1mcm93ID0gYygxLCAyKSkKaGlzdChkZWdyZWUobmV0KSwgbWFpbiA9ICJIaXN0b2dyYW0gb2Ygbm9kZSBkZWdyZWUiLCBicmVha3MgPSAxOnZjb3VudChuZXQpLTEsIHByb2IgPSBUUlVFLCB4bGltPXJhbmdlKGMoMCwgMzApKSkKaGlzdChkZWdyZWUocmFuZG9tX21vZGVsKSwgbWFpbiA9ICJIaXN0b2dyYW0gb2Ygbm9kZSBkZWdyZWUiLCBicmVha3MgPSAxOnZjb3VudChuZXQpLTEsIHByb2IgPSBUUlVFLCB4bGltPXJhbmdlKGMoMCwgMzApKSkKcGFyKG1mcm93ID0gYygxLCAxKSkKCmdsIDwtIHZlY3RvcignbGlzdCcsIDEwMCkKbSA8LSByZXAoTkEsIDEwMCkKZCA8LSByZXAoTkEsIDEwMCkKYSA8LSByZXAoTkEsIDEwMCkKZm9yIChpIGluIDE6MTAwKXsKICBnbFtbaV1dIDwtIHNhbXBsZV9zbWFsbHdvcmxkKGRpbSA9IDEsIHNpemUgPSBnb3JkZXIobmV0KSwgbmVpID0gbl9vZl9uZWksIHAgPSAwLjk5KQogIG1baV0gPC0gbWVhbl9kaXN0YW5jZShnbFtbaV1dKQogIGRbaV0gPC0gZGlhbWV0ZXIoZ2xbW2ldXSkKICBhW2ldIDwtIGlncmFwaDo6Y29tcG9uZW50cyhnbFtbaV1dKSRubwp9Cm1lYW5fZGlzdGFuY2UgPC0gbQpoaXN0KG1lYW5fZGlzdGFuY2UsIHhsaW09cmFuZ2UoYyhtaW4obSwgbWVhbl9kaXN0YW5jZShuZXQpKSwgbWF4KG0sIG1lYW5fZGlzdGFuY2UobmV0KSkpKSkKYWJsaW5lKHY9bWVhbl9kaXN0YW5jZShuZXQpLCBjb2w9J3JlZCcsIGx0eT0zLCBsd2Q9MikgCgpkaWFtZXRlciA8LSBkCmhpc3QoZGlhbWV0ZXIsIHhsaW09cmFuZ2UoYyhtaW4oZCwgZGlhbWV0ZXIobmV0LCB3ZWlnaHRzPU5BKSksIG1heChkLCBkaWFtZXRlcihuZXQsIHdlaWdodHM9TkEpKSkpKQphYmxpbmUodj1kaWFtZXRlcihuZXQsIHdlaWdodHM9TkEpLCBjb2w9J3JlZCcsIGx0eT0zLCBsd2Q9MikgCgpudW1iZXJfb2ZfY29tcG9uZW50cyA8LSBhCmhpc3QobnVtYmVyX29mX2NvbXBvbmVudHMsIHhsaW09cmFuZ2UoYygwLCAyNSkpKQphYmxpbmUodj1pZ3JhcGg6OmNvbXBvbmVudHMobmV0KSRubywgY29sPSdyZWQnLCBsdHk9MywgbHdkPTIpCmBgYAoKKirQkNC90LDQu9C+0LPQuNGH0L3QviDQv9GA0LXQtNGL0LTRg9GJ0LXQvNGDINGB0LvRg9GH0LDRjiwg0LTQsNC90L3QsNGPINC80L7QtNC10LvRjCDQv9C70L7RhdC+INC+0L/QuNGB0YvQstCw0LXRgiDRgdGC0YDRg9C60YLRg9GA0YMg0L3QsNGI0LXQs9C+INCz0YDQsNGE0LAuKiog0JfQvdCw0YfQuNC80L4g0YHQvtCy0L/QsNC00LDQtdGCINC70LjRiNGMINC00LjQsNC80LXRgtGALCDRgtCw0Log0LrQsNC6INC/0L4g0L3QtdC80YMg0LIg0YLQvtC8INGH0LjRgdC70LUg0L/RgNC+0LjRgdGF0L7QtNC40Lsg0L/QvtC00LHQvtGAINCz0LjQv9C10YDQv9Cw0YDQsNC80LXRgtGA0LAuCgrQoNCw0YHRgdC80L7RgtGA0LjQvCDRgtCw0LrQttC1ICoq0YHRhdC+0LbQtdGB0YLRjCDRgSDQvNC+0LTQtdC70YzRjiDQkdCw0YDQsNCx0LDRiNC4LdCQ0LvRjNCx0LXRgNGC0LAqKiwg0LLQutC70Y7Rh9Cw0Y7RidC10Lkg0L/RgNC10LTQv9C+0YfRgtC40YLQtdC70YzQvdC+0LUg0L/RgNC40YHQvtC10LTQuNC90LXQvdC40LUg0Log0L3QsNC40LHQvtC70LXQtSDRhtC10L3RgtGA0LDQu9GM0L3Ri9C8INCy0LXRgNGI0LjQvdCw0LwuCgpgYGB7cn0KIyDQk9C10L3QtdGA0LjRgNGD0LXQvCDQvNC+0LTQtdC70Ywg0JHQsNGA0LDQsdCw0YjQuC3QkNC70YzQsdC10YDRgtCwCiPQmNGJ0LXQvCDQvtC/0YLQuNC80LDQu9GM0L3QvtC1INC30L3QsNGH0LXQvdC40LUgcG93ZXIKbW9kZWwgPC0gdmVjdG9yKCdsaXN0JywgMTAwKQpyZXMgPC0gcmVwKE5BLCA0MCkKbSA8LSByZXAoTkEsIDEwMCkKZCA8LSByZXAoTkEsIDEwMCkKZm9yIChpIGluIGMoMTo0MCkpewogIG1vZGVsW1tpXV0gPC0gc2FtcGxlX3BhKG4gPSBnb3JkZXIobmV0KSwgcG93ZXIgPSBpLzEwLCBkaXJlY3RlZCA9IEZBTFNFKQogIG1baV0gPC0gbWVhbl9kaXN0YW5jZShtb2RlbFtbaV1dKQogIGRbaV0gPC0gZGlhbWV0ZXIobW9kZWxbW2ldXSkKICByZXNbaV0gPC0gKChtW2ldLW1lYW5fZGlzdF9uZXQpXjIrKGRbaV0tZGlhbV9uZXQpXjIpXigxLzIpIAp9CgojcG93ZXI9Mi4xNQoKcmFuZG9tX21vZGVsIDwtIHNhbXBsZV9wYShuID0gZ29yZGVyKG5ldCksIHBvd2VyID0gMi4xNSwgZGlyZWN0ZWQgPSBGQUxTRSkKcGFyKG1mcm93ID0gYygxLCAyKSkKaGlzdChkZWdyZWUobmV0KSwgbWFpbiA9ICJIaXN0b2dyYW0gb2Ygbm9kZSBkZWdyZWUiLCBicmVha3MgPSAxOnZjb3VudChuZXQpLTEsIHByb2IgPSBUUlVFLCB4bGltPXJhbmdlKGMoMCwgMjApKSkKaGlzdChkZWdyZWUocmFuZG9tX21vZGVsKSwgbWFpbiA9ICJIaXN0b2dyYW0gb2Ygbm9kZSBkZWdyZWUiLCBicmVha3MgPSAxOnZjb3VudChuZXQpLTEsIHByb2IgPSBUUlVFLCB4bGltPXJhbmdlKGMoMCwgMjApKSkKcGFyKG1mcm93ID0gYygxLCAxKSkKCmdsIDwtIHZlY3RvcignbGlzdCcsIDEwMCkKbSA8LSByZXAoTkEsIDEwMCkKZCA8LSByZXAoTkEsIDEwMCkKYSA8LSByZXAoTkEsIDEwMCkKZm9yIChpIGluIDE6MTAwKXsKICBnbFtbaV1dIDwtIHNhbXBsZV9wYShuID0gZ29yZGVyKG5ldCksIHBvd2VyID0gMi4xNSwgZGlyZWN0ZWQgPSBGQUxTRSkKICBtW2ldIDwtIG1lYW5fZGlzdGFuY2UoZ2xbW2ldXSkKICBkW2ldIDwtIGRpYW1ldGVyKGdsW1tpXV0pCiAgYVtpXSA8LSBpZ3JhcGg6OmNvbXBvbmVudHMoZ2xbW2ldXSkkbm8KfQptZWFuX2Rpc3RhbmNlIDwtIG0KaGlzdChtZWFuX2Rpc3RhbmNlLCB4bGltPXJhbmdlKGMobWluKG0sIG1lYW5fZGlzdGFuY2UobmV0KSksIG1heChtLCBtZWFuX2Rpc3RhbmNlKG5ldCkpKSkpCmFibGluZSh2PW1lYW5fZGlzdGFuY2UobmV0KSwgY29sPSdyZWQnLCBsdHk9MywgbHdkPTIpIAoKZGlhbWV0ZXIgPC0gZApoaXN0KGRpYW1ldGVyLCB4bGltPXJhbmdlKGMobWluKGQsIGRpYW1ldGVyKG5ldCwgd2VpZ2h0cz1OQSkpLCBtYXgoZCwgZGlhbWV0ZXIobmV0LCB3ZWlnaHRzPU5BKSkpKSkKYWJsaW5lKHY9ZGlhbWV0ZXIobmV0LCB3ZWlnaHRzPU5BKSwgY29sPSdyZWQnLCBsdHk9MywgbHdkPTIpIAoKbnVtYmVyX29mX2NvbXBvbmVudHMgPC0gYQpoaXN0KG51bWJlcl9vZl9jb21wb25lbnRzLCB4bGltPXJhbmdlKGMoMCwgMjUpKSkKYWJsaW5lKHY9aWdyYXBoOjpjb21wb25lbnRzKG5ldCkkbm8sIGNvbD0ncmVkJywgbHR5PTMsIGx3ZD0yKQoKYGBgCgrQmtCw0Log0LzRiyDQv9C+0LvRg9GH0LjQu9C4LCDQtNCw0L3QvdCw0Y8g0LzQvtC00LXQu9GMINGC0L7QttC1INC90LUg0L/QvtC00YXQvtC00LjRgiDQtNC70Y8g0L7Qv9C40YHQsNC90LjRjyDRgdGC0YDRg9C60YLRg9GA0Ysg0L3QvtCy0L7Qt9C10LvQsNC90LTRgdC60L7QuSDRgdC10YLQuDog0LLRgdC1INGB0YLQsNGC0LjRgdGC0LjRh9C10YHQutC4INC30L3QsNGH0LjQvNC+INC+0YLQu9C40YfQsNC10YLRgdGPLCDQutGA0L7QvNC1INC/0LDRgNCw0LzQtdGC0YDQsCwg0L/QviDQutC+0YLQvtGA0L7QvNGDINC/0YDQvtGF0L7QtNC40Lsg0L/QvtC00LHQvtGAINCz0LjQv9C10YDQv9Cw0YDQsNC80LXRgtGA0LAuCgojIyMjINCS0YvQstC+0LTRiwoKKirQktGL0LLQvtC00Ysg0L/QviAq0JfQsNC00LDQvdC40Y4gMio6Kiog0J3QuCDQvtC00L3QsCDQuNC3INGC0LXQvtGA0LXRgtC40YfQtdGB0LrQuNGFINC80L7QtNC10LvQtdC5LCDQuNC30LLQtdGB0YLQvdGL0YUg0L3QsNC8LCDQvdC1INC+0L/QuNGB0YvQstCw0LXRgiDRgdGC0YDRg9C60YLRg9GA0Ysg0L3QsNGI0LXQs9C+INCz0YDQsNGE0LAg0LTQvtGB0YLQsNGC0L7Rh9C90L4g0YLQvtGH0L3Qvi4KCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMjINCX0LDQtNCw0L3QuNC1IDMKCtCSINGN0YLQvtC8INC30LDQtNCw0L3QuNC4INC90LDQvCDQv9GA0LXQtNC70LDQs9Cw0LXRgtGB0Y8g0L/QvtGB0YfQuNGC0LDRgtGMINGA0LDQt9C70LjRh9C90YvQtSDQvNC10YDRiyAq0YbQtdC90YLRgNCw0LvRjNC90L7RgdGC0Lgg0LLQtdGA0YjQuNC9KiDQuCDRgdC00LXQu9Cw0YLRjCDRgdC+0LTQtdGA0LbQsNGC0LXQu9GM0L3Ri9C1INCy0YvQstC+0LTRiyDQvdCwINC+0YHQvdC+0LLQtSDQv9C+0LvRg9GH0LXQvdC90YvRhSDRgNCw0YHRh9C10YLQvtCyLgoK0JfQsNC80LXRh9Cw0L3QuNC1OiDQlNC70Y8g0LDQvdCw0LvQuNC30LAg0LjRgdC/0L7Qu9GM0LfRg9C10Lwg0L7QsdGA0LDRgtC90YvQtSDQstC10YHQsCwg0YIu0LouINC40YUg0LjRgdC/0L7Qu9GM0LfQvtCy0LDQvdC40LUg0LTQtdC70LDQtdGCINC+0YHQvNGL0YHQu9C10L3QvdGL0Lwg0YDQsNGB0YfQtdGCINGG0LXQvdGC0YDQsNC70YzQvdC+0YHRgtC4INC/0L4g0LHQu9C40LfQvtGB0YLQuCDQuCDQutGA0LDRgtGH0LDQudGI0LXQvNGDINC/0YPRgtC4LCDQvdC+INC90LUg0LjRgdC60LDQttCw0LXRgiDQvtGB0YLQsNC70YzQvdGL0YUg0LzQtdGAINGG0LXQvdGC0YDQsNC70YzQvdC+0YHRgtC4INCy0LXRgNGI0LjQvS4KCiMjIyMg0KbQtdC90YLRgNCw0LvRjNC90L7RgdGC0Ywg0L/QviDRgdGC0LXQv9C10L3QuAoK0JTQu9GPINC90LDRh9Cw0LvQsCDQv9C+0YHRh9C40YLQsNC10LwgKirRhtC10L3RgtGA0LDQu9GM0L3QvtGB0YLRjCDQv9C+INGB0YLQtdC/0LXQvdC4Kio6CgpgYGB7cn0KZGVnIDwtIGRlZ3JlZShuZXQpCgojIHBsb3QobmV0LCB2ZXJ0ZXgubGFiZWw9TkEsIGxheW91dD1sYXlvdXRfd2l0aF9mciwgdmVydGV4LnNpemU9ZGVnKQpgYGAKCtCi0LXQv9C10YDRjCDQv9C+0YHRgtGA0L7QuNC8ICrQs9C40YHRgtC+0LPRgNCw0LzQvNGDINGA0LDRgdC/0YDQtdC00LXQu9C10L3QuNGPINGB0YLQtdC/0LXQvdC10Lkg0LLQtdGA0YjQuNC9KjoKCmBgYHtyfQojINCz0LjRgdGC0L7Qs9GA0LDQvNC80LAg0YHRgtC10L/QtdC90LXQuSDQstC10YDRiNC40L0KaGlzdChkZWcsIG1haW49Ikhpc3RvZ3JhbSBvZiBub2RlIGRlZ3JlZSIsIGJyZWFrcz01MCwgcHJvYj1UUlVFKSAKIyDRgNCw0YHQv9GA0LXQtNC10LvQtdC90LjQtSDRgdGC0LXQv9C10L3QtdC5INCy0LXRgNGI0LjQvQoKbWVhbihkZWcpICMg0KHRgNC10LTQvdGP0Y8g0YHRgtC10L/QtdC90Ywg0LLQtdGA0YjQuNC90Ysg0L/QviDQs9GA0LDRhNGDCiMgfiA1LjY2Ck1vZGUoZGVnKSAjINCc0L7QtNCw0LvRjNC90LDRjyDRgdGC0LXQv9C10L3RjCDQstC10YDRiNC40L0g0LPRgNCw0YTQsAojIDEgLT4gNTk5INGA0LDQtwptZWRpYW4oZGVnKSAjINCc0LXQtNC40LDQvdCwINGB0YLQtdC/0LXQvdC10Lkg0LLQtdGA0YjQuNC9CiMgfiAyCnRvcF8xMF9kZWdyZWUgPC0gdGFpbChzb3J0KGRlZyksIDEwKSAjINGC0L7Qvy0xMCDQv9C+INGB0YLQtdC/0LXQvdGP0LwKdG9wXzEwX2RlZ3JlZSAjINCyINGC0L7Qv9C1IC0gNyDRg9C90LjQstC10YDRgdC40YLQtdGC0L7QsiwgMyDQs9C+0YEuINGD0YfRgNC10LbQtNC10L3QuNGPCmBgYAoKKirQktGL0LLQvtC0OioqINCm0LXQvdGC0YDQsNC70YzQvdC+0YHRgtGMINCy0LXRgNGI0LjQvSDQv9C+INGB0YLQtdC/0LXQvdC4INC90LUg0LfQsNCy0LjRgdC40YIg0L7RgiDQstC10YHQvtCyLiDQn9C+0LTQsNCy0LvRj9GO0YnQtdC1INCx0L7Qu9GM0YjQuNC90YHRgtCy0L4g0LLQtdGA0YjQuNC9INC40LzQtdC10YIg0YHRgtC10L/QtdC90YwsINC80LXQvdGM0YjRg9GOIGA1MGAuINCi0LDQuiwg0LzQtdC00LjQsNC90LAg0LrQvtC7LdCy0LAg0YHQvtGB0LXQtNC10Lkg0YDQsNCy0L3Rj9C10YLRgdGPIGByIHJvdW5kKG1lZGlhbihkZWcpKWAuINCSINGB0YDQtdC00L3QtdC8INGDINCy0LXRgNGI0LjQvdGLINGC0LDQutC+0LPQviDQs9GA0LDRhNCwINGB0YLQtdC/0LXQvdGMINGA0LDQstC90LAgYHIgcm91bmQobWVhbihkZWcpLCAyKWAuINCd0LDQuNCx0L7Qu9C10LUg0YfQsNGB0YLQviDQstGB0YLRgNC10YfQsNGO0YnQsNGP0YHRjyDRgdGC0LXQv9C10L3RjCDQstC10YDRiNC40L3RiyAtLS0gMSwg0LrQvtGC0L7RgNCw0Y8g0LLRgdGC0YDQtdGH0LDQtdGC0YHRjyA1OTkg0YDQsNC3LiDQldGB0LvQuCDQvNGLINC/0L7RgdC80L7RgtGA0LjQvCAxMCDQstC10YDRiNC40L0g0YEg0L3QsNC40LHQvtC70YzRiNC40Lwg0YfQuNGB0LvQvtC8INGB0L7RgdC10LTQtdC5LCDRgtC+INC+0LrQsNC20LXRgtGB0Y8sINGH0YLQviA3INC40Lcg0L3QuNGFINGP0LLQu9GP0Y7RgtGB0Y8g0YPQvdC40LLQtdGA0YHQuNGC0LXRgtCw0LzQuCwg0LIg0YfQuNGB0LvQtSDQutC+0YLQvtGA0YvRhSDQutGA0YPQv9C90LXQudGI0LjQuSAtLS0g0YPQvdC40LLQtdGA0YHQuNGC0LXRgiDQntC60LvQtdC90LTQsCAo0YHRgtC10L/QtdC90Ywg0LLQtdGA0YjQuNC90Ysg0LzQsNC60YHQuNC80LDQu9GM0L3QsNGPIC0tLSBgciBtYXgoZGVnKWApLiDQntGB0YLQsNCy0YjQuNC10YHRjyAzINC+0YDQs9Cw0L3QuNC30LDRhtC40Lgg0Y/QstC70Y/RjtGC0YHRjyDQs9C+0YHRg9C00LDRgNGB0YLQstC10L3QvdGL0LzQuDogMiDQtNC10L/QsNGA0YLQsNC80LXQvdGC0LAg0LfQtNGA0LDQstC+0L7RhdGA0LDQvdC10L3QuNGPINC4IDEg0LjRgdGB0LvQtdC00L7QstCw0YLQtdC70YzRgdC60LDRjyDQutC+0LzQv9Cw0L3QuNGPLiDQodGC0LXQv9C10L3RjCDRgyDQstGB0LXRhSDQstC10YDRiNC40L0sINCy0YXQvtC00Y/RidC40YUg0LIg0YLQvtC/LTEwLCBcPiAxMDAuCgojIyMjINCm0LXQvdGC0YDQsNC70YzQvdC+0YHRgtGMINC/0L4g0LHQu9C40LfQvtGB0YLQuAoK0JTQsNC70LXQtSDRgNCw0YHRgdGH0LjRgtCw0LXQvCAqKtGG0LXQvdGC0YDQsNC70YzQvdC+0YHRgtGMINC/0L4g0LHQu9C40LfQvtGB0YLQuCoqINC00LLRg9C80Y8g0YHQv9C+0YHQvtCx0LDQvNC4OiDQkiDQv9C10YDQstC+0Lwg0LLQsNGA0LjQsNC90YLQtSDQstGB0LUg0LLQtdGB0LAg0YDQtdCx0LXRgCDQs9GA0LDRhNCwINGP0LLQu9GP0Y7RgtGB0Y8gYDFgLCDQsiDQtNGA0YPQs9C+0Lwg0LjRgdC/0L7Qu9GM0LfRg9GO0YLRgdGPINC+0LHRgNCw0YLQvdGL0LUg0LLQtdGB0LAg0YDQtdCx0LXRgC4KCmBgYHtyfQpjbG9zMSA8LSBjbG9zZW5lc3MobmV0LCB3ZWlnaHRzPU5BKSAjINCf0LXRgNCy0YvQuSDRgdC/0L7RgdC+0LEgLSDQsdC10Lcg0YPRh9C10YLQsCDQstC10YHQvtCyCiMgY2xvczEKCnBsb3QobmV0LCB2ZXJ0ZXgubGFiZWw9TkEsIGxheW91dD1sYXlvdXRfd2l0aF9mciwgdmVydGV4LnNpemU9Y2xvczEgKiA1MCkKYGBgCgpgYGB7cn0KdG9wXzEwX2Nsb3MxIDwtIHRhaWwoc29ydChjbG9zMSksIDEwKSAKIyDQktC10LrRgtC+0YAt0YLQvtC/IDQyINGC0LDQutC20LUg0LHRg9C00LXRgiDQtdC00LjQvdC40YfQvdGL0LwsINCwINCy0L7RgiDQstC10LrRgtC+0YAt0YLQvtC/IDQzINGD0LbQtSDQvdC10YIKdG9wXzEwX2Nsb3MxCgpib3R0b21fMTBfY2xvczEgPC0gaGVhZChzb3J0KGNsb3MxKSwgMTApCmJvdHRvbV8xMF9jbG9zMQoKY2xvczFbIlVuaXZlcnNpdHkgb2YgQXVja2xhbmQiXQpgYGAKCmBgYHtyfQpjbG9zMiA8LSBjbG9zZW5lc3MobmV0KQojIGNsb3MyCgpwbG90KG5ldCwgdmVydGV4LmxhYmVsPU5BLCBsYXlvdXQ9bGF5b3V0X3dpdGhfZnIsIHZlcnRleC5zaXplPWNsb3MyICogNTApCmBgYAoKYGBge3J9CnRvcF8xMF9jbG9zMiA8LSB0YWlsKHNvcnQoY2xvczIpLCAxMCkgCnRvcF8xMF9jbG9zMgoKYm90dG9tXzEwX2Nsb3MyIDwtIGhlYWQoc29ydChjbG9zMiksIDEwKQpib3R0b21fMTBfY2xvczIKCmNsb3MyWyJVbml2ZXJzaXR5IG9mIEF1Y2tsYW5kIl0KYGBgCgoqKtCS0YvQstC+0LQ6Kiog0JIg0L7QsdC+0LjRhSDRgdC70YPRh9Cw0Y/RhSDQvNCw0LrRgdC40LzQsNC70YzQvdCw0Y8g0YbQtdC90YLRgNCw0LvRjNC90L7RgdGC0Ywg0LLQtdGA0YjQuNC9INCx0YPQtNC10YIg0YHQvtGB0YLQsNCy0LvRj9GC0YwgYDFgLiDQkiDQvdCw0YjQtdC8INCz0YDQsNGE0LUg0YHRg9GJ0LXRgdGC0LLRg9C10YIgMjEg0L/QsNGA0LAg0LLQtdGA0YjQuNC9LCDQutC+0YLQvtGA0LDRjyDRgdCy0Y/Qt9Cw0L3QsCDQu9C40YjRjCDQvNC10LbQtNGDINGB0L7QsdC+0Lkg0Lgg0LHQvtC70LXQtSDQvdC4INGBINC60LXQvCAo0LjQtyDRgNCw0YHRgdGH0LXRgtCwINC00LvRjyDQs9GA0LDRhNCwINGBINC10LTQuNC90LjRh9C90YvQvNC4INCy0LXRgdCw0LzQuCDRgNC10LHQtdGAKS4g0JjQtyDQvdC40YUg0LvQuNGI0YwgNSDQvtGA0LPQsNC90LjQt9Cw0YbQuNC5INGA0LDQsdC+0YLQsNC70Lgg0YHQvtCy0LzQtdGB0YLQvdC+INCx0L7Qu9C10LUgMSDRgNCw0LfQsCAo0LjQtyDRgNCw0YHRgdGH0LXRgtCwINC00LvRjyDQs9GA0LDRhNCwINGBINC+0LHRgNCw0YLQvdGL0LzQuCDQstC10YHQsNC80LgpLiDQotC+0L8tMTAg0YbQtdC90YLRgNCw0LvRjNC90YvRhSDQstC10YDRiNC40L0g0L/QviDQsdC70LjQt9C+0YHRgtC4INC4INGC0L7Qvy0xMCDQv9C+INGB0YLQtdC/0LXQvdC4INGD0LbQtSDRgdGD0YnQtdGB0YLQstC10L3QvdC+INGA0LDQt9C70LjRh9Cw0Y7RgtGB0Y8uINCi0LDQuiwg0YbQtdC90YLRgNCw0LvRjNC90L7RgdGC0Ywg0L/QviDQsdC70LjQt9C+0YHRgtC4INGD0L3QuNCy0LXRgNGB0LjRgtC10YLQsCDQntC60LvQtdC90LTQsCDRgdC+0YHRgtCw0LLQuNGCIGByIGNsb3MxWyJVbml2ZXJzaXR5IG9mIEF1Y2tsYW5kIl1gINCyINC/0LXRgNCy0L7QvCDRgdC70YPRh9Cw0LUg0LggYHIgY2xvczFbIlVuaXZlcnNpdHkgb2YgQXVja2xhbmQiXWAuINCiLtC1LiBgcm91bmQoMSAvIGNsb3MxWyJVbml2ZXJzaXR5IG9mIEF1Y2tsYW5kIl0pYCDQuNC70LggYHJvdW5kKDEgLyBjbG9zMlsiVW5pdmVyc2l0eSBvZiBBdWNrbGFuZCJdKWAgLS0tINGB0YPQvNC80LAg0LTQu9C40L0g0LLRgdC10YUg0L/Rg9GC0LXQuSDQvtGCINGD0L3QuNCy0LXRgNGB0LjRgtC10YLQsCDQntC60LvQtdC90LTQsCDQtNC+INC70Y7QsdC+0Lkg0LTRgNGD0LPQvtC5INCy0LXRgNGI0LjQvdGLINCyINC30LDQstC40YHQuNC80L7RgdGC0Lgg0L7RgiDQvNC10YLQvtC00LAg0YDQsNGB0YHRh9C10YLQsC4KCiMjIyMg0KbQtdC90YLRgNCw0LvRjNC90L7RgdGC0Ywg0L/QviDQutGA0LDRgtGH0LDQudGI0LXQvNGDINC/0YPRgtC4CgpgYGB7cn0KYmV0dzEgPC0gYmV0d2Vlbm5lc3MobmV0LCB3ZWlnaHRzPU5BKQpoZWFkKGJldHcxKQoKdG9wXzEwX2JldHcxIDwtIHRhaWwoc29ydChiZXR3MSksIDEwKQp0b3BfMTBfYmV0dzEKCmJvdHRvbV8xMF9iZXR3MSA8LSBoZWFkKHNvcnQoYmV0dzEpLCAxMCkKYm90dG9tXzEwX2JldHcxCgpiZXR3MVsiVW5pdmVyc2l0eSBvZiBBdWNrbGFuZCJdCmBgYAoKYGBge3J9CmJldHcyIDwtIGJldHdlZW5uZXNzKG5ldCkKaGVhZChiZXR3MikKCnRvcF8xMF9iZXR3MiA8LSB0YWlsKHNvcnQoYmV0dzIpLCAxMCkKdG9wXzEwX2JldHcyCgpib3R0b21fMTBfYmV0dzIgPC0gaGVhZChzb3J0KGJldHcyKSwgMTApCmJvdHRvbV8xMF9iZXR3MgoKYmV0dzJbIlVuaXZlcnNpdHkgb2YgQXVja2xhbmQiXQpgYGAKCioq0JLRi9Cy0L7QtDoqKiDQn9GA0Lgg0YDQsNC30L3Ri9GFINC80LXRgtC+0LTQsNGFINC80LjQvdC40LzQsNC70YzQvdGL0LUg0LfQvdCw0YfQtdC90LjRjyDRhtC10L3RgtGA0LDQu9GM0L3QvtGB0YLQuCDRgyDQstC10YDRiNC40L0g0LHRg9C00YPRgiDRgNCw0LLQvdGLIGAwYC4g0K3RgtC+INCy0LXRgNGI0LjQvdGLLCDRgNCw0YHQv9C+0LvQvtC20LXQvdC90YvQtSDQvdCwINC/0LXRgNC40YTQtdGA0LjQuCDQs9GA0LDRhNCwLCDQuNC70Lgg0YLQtSwg0LrQvtGC0L7RgNGL0LUg0LLQvtCy0YHQtSDQuNC80LXRjtGCINCy0YHQtdCz0L4g0L7QtNC90L7Qs9C+INGB0L7RgdC10LTQsCAo0L3QsNC/0YDQuNC80LXRgCwg0YLQsCAyMSDQv9Cw0YDQsCDQstC10YDRiNC40L0pLiDQnNCw0LrRgdC40LzQsNC70YzQvdGL0LUg0YbQtdC90YLRgNCw0LvRjNC90L7RgdGC0Lgg0LLQtdGA0YjQuNC9INC/0YDQtdCy0YvRiNCw0Y7RgiBgNDAgMDAwYCDQsiDRgtC+0L8tMTAuINCSINC+0LHQvtC40YUg0YHQu9GD0YfQsNGP0YUg0YPQvdC40LLQtdGA0YHQuNGC0LXRgiDQntC60LvQtdC90LTQsCDQvdCwINC/0LXRgNCy0L7QvCDQvNC10YHRgtC1IChgciBtYXgoYmV0dzEpYCDQuCBgciBtYXgoYmV0dzIpYCkuINCX0L3QsNGH0LjRgtC10LvRjNC90L7QtSDRh9C40YHQu9C+INC60YDQsNGC0YfQsNC50YjQuNGFINC/0YPRgtC10Lkg0LzQtdC20LTRgyDQu9GO0LHRi9C80Lgg0LTQstGD0LzRjyDQstC10YDRiNC40L3QsNC80Lgg0L/RgNC+0YXQvtC00LjRgiDQuNC80LXQvdC90L4g0YfQtdGA0LXQtyDQtNCw0L3QvdGL0Lkg0YPQvdC40LLQtdGA0YHQuNGC0LXRgi4KCiMjIyMg0KbQtdC90YLRgNCw0LvRjNC90L7RgdGC0Ywg0L/QviDRgdC+0LHRgdGC0LLQtdC90L3QvtC80YMg0LfQvdCw0YfQtdC90LjRjgoKYGBge3J9CmVpZzEgPC0gZWlnZW5fY2VudHJhbGl0eShuZXQsIHdlaWdodHMgPSBOQSkKIyBoZWFkKGVpZzEpCgp0b3BfMTBfZWlnMSA8LSB0YWlsKHNvcnQoZWlnMSR2ZWN0b3IpLCAxMCkKdG9wXzEwX2VpZzEKCmJvdHRvbV8xMF9laWcxIDwtIGhlYWQoc29ydChlaWcxJHZlY3RvciksIDEwKQpib3R0b21fMTBfZWlnMQpgYGAKCmBgYHtyfQplaWcyIDwtIGVpZ2VuX2NlbnRyYWxpdHkobmV0KQojIGhlYWQoZWlnMikKCnRvcF8xMF9laWcyIDwtIHRhaWwoc29ydChlaWcyJHZlY3RvciksMTApCnRvcF8xMF9laWcyCgpib3R0b21fMTBfZWlnMiA8LSBoZWFkKHNvcnQoZWlnMiR2ZWN0b3IpLDEwKQpib3R0b21fMTBfZWlnMgpgYGAKCioq0JLRi9Cy0L7QtDoqKiDQnNC40L3QuNC80LDQu9GM0L3Ri9C1INC30L3QsNGH0LXQvdC40Y8g0YbQtdC90YLRgNCw0LvRjNC90L7RgdGC0LXQuSDQv9C+INGB0L7QsdGB0YLQstC10L3QvdC+0LzRgyDQt9C90LDRh9C10L3QuNGOINGC0LDQutC20LUg0YHQvtGB0YLQsNCy0LvRj9GO0YIgYDBgLiDQndCw0LjQsdC+0LvRjNGI0YPRjiDQttC1INC40LzQtdC10YIg0YPQvdC40LLQtdGA0YHQuNGC0LXRgiDQntC60LvQtdC90LTQsC4g0JXQs9C+INCy0YvRgdC+0LrQuNC5INC/0L7QutCw0LfQsNGC0LXQu9GMINCz0L7QstC+0YDQuNGCLCDRh9GC0L4g0YHQsNC8INGD0L3QuNCy0LXRgNGB0LjRgtC10YIg0YHQstGP0LfQsNC9INGB0L4g0LzQvdC+0LPQuNC80Lgg0LLQtdGA0YjQuNC90LDQvNC4LCDQutC+0YLQvtGA0YvQtSDQsiDRgdCy0L7RjiDQvtGH0LXRgNC10LTRjCDQuNC80LXRjtGCINGC0LDQutC20LUg0LLRi9GB0L7QutC+0LUg0LfQvdCw0YfQtdC90LjQtSDRhtC10L3RgtGA0LDQu9GM0L3QvtGB0YLQuC4KCiMjIyMg0JLRi9Cy0L7QtNGLCgpgYGB7cn0KIyDQvtCx0YrQtdC00LjQvdC40Lwg0LLRgdC1INGG0LXQvdGC0YDQsNC70YzQvdC+0YHRgtC4INCyINC+0LTQuNC9INC00LDRgtCw0YTRgNC10LnQvCDQuCDQv9C+0YHQvNC+0YLRgNC40Lwg0LrQvtGA0YDQtdC70Y/RhtC40Lgg0LIg0LTQstGD0YUg0LLQsNGA0LjQsNC90YLQsNGFIApkZjEgPC0gZGF0YS5mcmFtZShkZWcsIGNsb3MxLCBiZXR3MSwgZWlnMSR2ZWN0b3IpCmNvcihkZjEpCgpkZjIgPC0gZGF0YS5mcmFtZShkZWcsIGNsb3MyLCBiZXR3MiwgZWlnMiR2ZWN0b3IpCmNvcihkZjIpCmBgYAoKKirQktGL0LLQvtC0OioqINCh0L7RgdGC0LDQstC40LIg0LrQvtGA0YDQtdC70Y/RhtC40L7QvdC90YvQtSDQvNCw0YLRgNC40YbRiyDQt9Cw0LzQtdGC0LjQvCwg0YfRgtC+INGB0YPRidC10YHRgtCy0YPQtdGCINCy0YvRgdC+0LrQsNGPINC60L7RgNGA0LXQu9GP0YbQuNGPINC80LXQttC00YMg0YHQu9C10LTRg9GO0YnQuNC80Lgg0L/QsNGA0LDQvNC4INGG0LXQvdGC0YDQsNC70YzQvdC+0YHRgtC10Lkg0LLQtdGA0YjQuNC9OiDQv9C+INGB0YLQtdC/0LXQvdC4IC0g0L/QviDQutGA0LDRgtGH0LDQudGI0LXQvNGDINGA0LDRgdGB0YLQvtGP0L3QuNGOLCDQv9C+INGB0YLQtdC/0LXQvdC4IC0g0L/QviDRgdC+0LHRgdGC0LIuINC30L3QsNGH0LXQvdC40Y4g0Lgg0L/QviDRgdC+0LHRgdGC0LIuINC30L3QsNGH0LXQvdC40Y4gLSDQv9C+INC60YDQsNGC0YfQsNC50YjQtdC80YMg0YDQsNGB0YHRgtC+0Y/QvdC40Y4KCtCh0YDQsNCy0L3QuNC8LCDQutCw0LrQuNC1INC+0YDQs9Cw0L3QuNC30LDRhtC40Lgg0L/QvtC/0LDQtNCw0LvQuCDQsiDRgtC+0L/RiyDQv9C+INGG0LXQvdGC0YDQsNC70YzQvdC+0YHRgtGP0LwgKNC40YHQutC70Y7Rh9Cw0Y8g0YbQtdC90YLRgNCw0LvRjNC90L7RgdGC0Ywg0L/QviDQsdC70LjQt9C+0YHRgtC4KS4KCmBgYHtyfQoKY29ycjEgPC0gZGF0YS5mcmFtZSgKICBuYW1lcyh0b3BfMTBfZGVncmVlKSwgCiAgbmFtZXModG9wXzEwX2JldHcxKSwgCiAgbmFtZXModG9wXzEwX2VpZzEpCikKY29ycjEKCmNvcnIyIDwtIGRhdGEuZnJhbWUoCiAgbmFtZXModG9wXzEwX2RlZ3JlZSksIAogIG5hbWVzKHRvcF8xMF9iZXR3MiksIAogIG5hbWVzKHRvcF8xMF9laWcyKQopCmNvcnIyCmBgYAoKKirQktGL0LLQvtC00Ysg0L/QviDQl9Cw0LTQsNC90LjRjiAzOioqINCh0YDQsNCy0L3QuNCyINGC0L7Qv9GLINC/0L4g0LzQsNC60YHQuNC80LDQu9GM0L3Ri9C8INGG0LXQvdGC0YDQsNC70YzQvdC+0YHRgtGP0LwgKNC30LAg0LjRgdC60LvRjtGH0LXQvdC40LXQvCDRgtC+0L/QsCDRhtC10L3RgtGA0LDQu9GM0L3QvtGB0YLQtdC5INC/0L4g0LHQu9C40LfQvtGB0YLQuCDQuNC3LdC30LAg0LzQsNC70L7Qs9C+INC60L7Qu9C40YfQtdGB0YLQstCwINGB0L7RgdC10LTQtdC5IFvQv9C+0YDRj9C00LrQsCAxXSksINC30LDQvNC10YLQuNC8LCDRh9GC0L4g0L/QviDRgtGA0LXQvCDRhtC10L3RgtGA0LDQu9GM0L3QvtGB0YLRj9C8INC/0LXRgNCy0YPRjiDQv9GP0YLQtdGA0LrRgyDQt9Cw0L3QuNC80LDRjtGCINC+0LTQvdC4INC4INGC0LUg0LbQtSDQvtGA0LPQsNC90LjQt9Cw0YbQuNC4OiDRg9C90LjQstC10YDRgdC40YLQtdGCINCe0LrQu9C10L3QtNCwLCDRg9C90LjQstC10YDRgdC40YLQtdGCINCe0YLQsNCz0L4sINGD0L3QuNCy0LXRgNGB0LjRgtC10YIg0JzRjdGB0YHQuCwg0YPQvdC40LLQtdGA0YHQuNGC0LXRgiDQmtCw0L3RgtC10YDQsdC10YDQuCDQuCDQktC40LrRgtC+0YDQuNCw0L3RgdC60LjQuSDRg9C90LjQstC10YDRgdC40YLQtdGCINCS0LXQu9C70LjQvdCz0YLQvtC90LAuCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIyDQl9Cw0LTQsNC90LjQtSA0CgrQkiAq0JfQsNC00LDQvdC40LggNCog0L3QsNC8INC/0YDQtdC00LvQsNCz0LDQtdGC0YHRjyDRgNCw0YHRgdGH0LjRgtCw0YLRjCAq0LDRgdGB0L7RgNGC0LDRgtC40LLQvdC+0YHRgtGMKiDQuCAq0LPQvtC80L7RhNC40LvQuNGOKiDQtNC70Y8g0LPRgNCw0YTQsC4g0J3QsNGH0L3QtdC8INC40YHRgdC70LXQtNC+0LLQsNC90LjQtSDQtNCw0L3QvdGL0YUg0YEgKtCw0YHRgdC+0YDRgtCw0YLQuNCy0L3QvtGB0YLQuCo6CgojIyMjINCQ0YHRgdC+0YDRgtCw0YLQuNCy0L3QvtGB0YLRjAoKYGBge3J9CiMg0JLQvtC30L3QuNC60LvQuCDQv9GA0L7QsdC70LXQvNGLINGBINCy0YvRh9C40YHQu9C10L3QuNC10Lwg0LDRgdGB0L7RgNGC0LDRgtC40LLQvdC+0YHRgtC4INGH0LXRgNC10LcKIyBhc3NvcnRhdGl2aXR5X25vbWluYWwobmV0LCB0eXBlcz1WKG5ldCkkdHlwZSwgZGlyZWN0ZWQ9RikgCiMg0J/RgNC10LTRg9C/0YDQtdC20LTQtdC90LjQtTog0LIg0YDQtdC30YPQu9GM0YLQsNGC0LUg0L/RgNC10L7QsdGA0LDQt9C+0LLQsNC90LjRjyDRgdC+0LfQtNCw0L3RiyBOQQojIFsxXSBOYU4KYXNzb3J0YXRpdml0eV9ub21pbmFsKG5ldCwgdHlwZXM9VihuZXQpJHR5cGUsIGRpcmVjdGVkPUYpCmBgYAoKYGBge3J9CiMg0J/QvtGN0YLQvtC80YMg0LHRi9C70L4g0L/RgNC40L3Rj9GC0L4g0YDQtdGI0LXQvdC40LUg0YHQvtC30LTQsNGC0Ywg0L3QvtCy0YvQuSDRgdGC0L7Qu9Cx0LXRhiDRgSDQt9Cw0LrQvtC00LjRgNC+0LLQsNC90L3Ri9C80Lgg0YHRgtGA0L7QutCw0LzQuAoKVihuZXQpJG51bV90eXBlIDwtIGlmZWxzZSggVihuZXQpJHR5cGU9PSJCdXNpbmVzcyBFbnRlcnByaXNlIiwgMSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKCBWKG5ldCkkdHlwZT09IlByaXZhdGUgbm90IGZvciBwcm9maXQiLCAyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKCBWKG5ldCkkdHlwZT09IkdvdmVybm1lbnQiLCAzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSggVihuZXQpJHR5cGU9PSJIaWdoZXIgRWR1Y2F0aW9uIiwgNCwgMCkgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkgCiAgICAgICAgICAgICAgICAgICAgICAgICAgKSAKICAgICAgICAgICAgICAgICAgICAgICApCmBgYAoKYGBge3J9CmFzc29ydF9ub20gPC0gYXNzb3J0YXRpdml0eV9ub21pbmFsKG5ldCwgdHlwZXM9VihuZXQpJG51bV90eXBlLCBkaXJlY3RlZD1GKSAKYXNzb3J0X25vbSAjIC0wLjA1ODc2Mjk4CmBgYAoKYGBge3J9CiMg0LfQvdCw0YfQtdC90LjQtSDQsNGB0YHQvtGA0YLQsNGC0LjQstC90L7RgdGC0Lgg0L3QtSDQt9Cw0LLQuNGB0LjRgiDQvtGCINC60L7QvdC60YDQtdGC0L3Ri9GFINGH0LjRgdC10LsKVihuZXQpJG51bV90eXBlMSA8LSBpZmVsc2UoIFYobmV0KSR0eXBlPT0iQnVzaW5lc3MgRW50ZXJwcmlzZSIsIDIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoIFYobmV0KSR0eXBlPT0iUHJpdmF0ZSBub3QgZm9yIHByb2ZpdCIsIDcsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWZlbHNlKCBWKG5ldCkkdHlwZT09IkdvdmVybm1lbnQiLCA1LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmZWxzZSggVihuZXQpJHR5cGU9PSJIaWdoZXIgRWR1Y2F0aW9uIiwgMTAsIDApIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgKSAKICAgICAgICAgICAgICAgICAgICAgICAgKQpgYGAKCmBgYHtyfQphc3NvcnRhdGl2aXR5X25vbWluYWwobmV0LCB0eXBlcz1WKG5ldCkkbnVtX3R5cGUxLCBkaXJlY3RlZD1GKSAjIC0wLjA1ODc2Mjk4CmBgYAoKYGBge3J9CiMg0YHRh9C40YLQsNC10Lwg0LDRgdGB0L7RgNGC0LDRgtC40LLQvdC+0YHRgtGMINC/0L4g0YHRgtC10L/QtdC90Lgg0LLQtdGA0YjQuNC90YsKYXNzb3J0X2RlZyA8LSBhc3NvcnRhdGl2aXR5X2RlZ3JlZShuZXQsIGRpcmVjdGVkPUYpICMgLTAuMzM2MTc0OQphc3NvcnRfZGVnCmBgYAoKKirQntCx0L7QsdGJ0LXQvdC40LUg0YDQtdC30YPQu9GM0YLQsNGC0L7QsjoqKiAq0JDRgdGB0L7RgNGC0LDRgtC40LLQvdC+0YHRgtGMKiDQsiDQs9GA0LDRhNC1INC/0L4g0YLQuNC/0YMg0LLQtdGA0YjQuNC9INC/0YDQuNC80LXRgNC90L4g0YDQsNCy0L3QsCBgciByb3VuZChhc3NvcnRfbm9tLCAzKWAuINCt0YLQviDQvtC30L3QsNGH0LDQtdGCLCDRh9GC0L4g0LzRiyDQvdC1INC80L7QttC10Lwg0YPRgtCy0LXRgNC20LTQsNGC0Ywg0L3QsNC70LjRh9C40LUg0L/RgNC10LTQv9C+0YfRgtC40YLQtdC70YzQvdC+0LPQviDQv9GA0LjRgdC+0LXQtNC40L3QtdC90LjRjyDRg9C30LvQvtCyINGB0LXRgtC4INC6INGB0LLQvtC10LzRgyDRgtC40L/RgyAo0YHRgNC10LTQuCDRg9C30LvQvtCyINCyINC+0LHRidC10LwsINGCLtC1LiDRgdGA0LXQtNC4INGD0LfQu9C+0LIg0LLRgdC10YUg0YLQuNC/0L7QsikuCgoq0JDRgdGB0L7RgNGC0LDRgtC40LLQvdC+0YHRgtGMKiDQv9C+INGB0YLQtdC/0LXQvdC4INCy0LXRgNGI0LjQvdGLINGB0L7RgdGC0LDQstC70Y/QtdGCINC/0YDQuNC80LXRgNC90L4gYHIgcm91bmQoYXNzb3J0X2RlZywgMylgLCDRh9GC0L4g0LPQvtCy0L7RgNC40YIg0L4g0L/RgNC10LTQv9C+0YfRgtC40YLQtdC70YzQvdC+0Lwg0L/RgNC40YHQvtC10LTQuNC90LXQvdC40Lgg0YPQt9C70L7QsiDQuiDQstC10YDRiNC40L3QsNC8INGBINC+0YLQvdC+0YHQuNGC0LXQu9GM0L3QviDQvdC10LHQvtC70YzRiNC40Lwg0LrQvtC70LjRh9C10YHRgtCy0L7QvCDRgdC+0YHQtdC00LXQuS4KCj4g0JTQu9GPINCy0YvRj9Cy0LvQtdC90LjRjyDQsdC+0LvQtdC1INGC0L7Rh9C90L7Qs9C+INGN0YTRhNC10LrRgtCwINC/0YDQtdC00L/QvtGH0YLQuNGC0LXQu9GM0L3QvtCz0L4g0L/RgNC40YHQvtC10LTQuNC90LXQvdC40Y8g0LjQvNC10L3QvdC+INGB0YDQtdC00Lgg0YPQvdC40LLQtdGA0YHQuNGC0LXRgtC+0LIgKNGH0YLQviDQuNC90YLQtdGA0LXRgdGD0LXRgiDQvdCw0YEg0LIg0YDQsNC80LrQsNGFINC40YHRgdC70LXQtNC+0LLQsNGC0LXQu9GM0YHQutC+0LPQviDQstC+0L/RgNC+0YHQsCkg0YDQsNGB0YHRh9C40YLQsNC10Lwg0L/QvtC60LDQt9Cw0YLQtdC70Lgg0LPQvtC80L7RhNC40LvQuNC4INC00LvRjyDRg9C90LjQstC10YDRgdC40YLQtdGC0L7QsiDQuCDQtNGA0YPQs9C40YUg0YLQuNC/0L7QsiDQuNC90YHRgtC40YLRg9GC0L7Qsi4KCtCd0LDQvNC4INCx0YvQu9C+INC/0YDQuNC90Y/RgtC+INGA0LXRiNC10L3QuNC1INGA0LDRgdGB0YfQuNGC0LDRgtGMICpkeWFkaWNpdHkqICjQtdC1INC/0L7RgdGH0LjRgtCw0LXQvCDRgtC+0LvRjNC60L4g0LTQu9GPINC+0LTQvdC+0LPQviDRgdC70YPRh9Cw0Y8sINGCLtC6LiDQvtC90LAg0L3QtSDQsdGD0LTQtdGCINC80LXQvdGP0YLRjNGB0Y8g0L/RgNC4INGA0LDQt9C70LjRh9C90YvRhSDRgNCw0LfQsdC40LXQvdC40Y/RhSkg0LggKmhldGVyb3BoaWxpY2l0eSog0YPRh9GA0LXQttC00LXQvdC40Lkg0LLRi9GB0YjQtdCz0L4g0L7QsdGA0LDQt9C+0LLQsNC90LjRjyDQtNC70Y8g0YHQu9C10LTRg9GO0YnQuNGFINGA0LDQt9C00LXQu9C10L3QuNC5INC90LAg0L/QvtC00LPRgNGD0L/Qv9GLOiAtIGBIaWdoZXIgRWR1Y2F0aW9uYCB2cyDQstGB0LUg0L7RgdGC0LDQu9GM0L3Ri9C1IC0gYEhpZ2hlciBFZHVjYXRpb25gIHZzIGBCdXNpbmVzcyBFbnRlcnByaXNlYCAtIGBIaWdoZXIgRWR1Y2F0aW9uYCB2cyBgR292ZXJubWVudGAuCgrQl9Cw0LzQtdGH0LDQvdC40LU6INCS0LvQuNGP0L3QuNC10LwgYFByaXZhdGUgbm90IGZvciBwcm9maXRgINC80L7QttC90L4g0L/RgNC10L3QtdCx0YDQtdGH0YwuCgojIyMjIGBIaWdoZXIgRWR1Y2F0aW9uYCB2cyDQstGB0LUg0L7RgdGC0LDQu9GM0L3Ri9C1CgpgYGB7cn0KcCA8LSBlZGdlX2RlbnNpdHkobmV0KQpwICMgMC4wMDM3NDU2MDEKbl9jIDwtIHN1bSggVihuZXQpJHR5cGUgPT0gJ0hpZ2hlciBFZHVjYXRpb24nICkKbl9jICMgNTQKZXhwX2RpYWRfdW5pIDwtIG5fYyAqIChuX2MgLSAxKSAvIDIgKiBwCmV4cF9kaWFkX3VuaSAjIDUuMzU5OTU1Cgp1bmlzIDwtIFYobmV0KVt3aGljaCggVihuZXQpJHR5cGUgPT0gJ0hpZ2hlciBFZHVjYXRpb24nICldCnVuaXMgPC0gbmFtZXModW5pcykKIyB1bmlzCgptX2MgPC0gMAoKZm9yIChyb3cgaW4gMTpucm93KGVkZ2VzKSkgewogIGZyb21fb2JqIDwtIGVkZ2VzW3JvdywgJ2Zyb20nXQogIHRvX29iaiA8LSBlZGdlc1tyb3csICd0byddCiAgCiAgaWYgKCAoZnJvbV9vYmogJWluJSB1bmlzKSAmJiAodG9fb2JqICVpbiUgdW5pcykgKSB7CiAgICBtX2MgPC0gbV9jICsgMQogIH0KfQoKbV9jICMgMTcyCgpkaWFkaWNpdHlfdW5pIDwtIG1fYyAvIGV4cF9kaWFkX3VuaSAKZGlhZGljaXR5X3VuaSAjIDMyLjA4OTgyCmBgYAoKYGBge3J9CiMgMi3QuSDRgdC/0L7RgdC+0LEg0L/QvtGB0YfQuNGC0LDRgtGMIGR5YWRpY2l0eQp1bmlfbmV0IDwtIGluZHVjZWRfc3ViZ3JhcGgoIAogIG5ldCwgCiAgdj1WKG5ldClbd2hpY2goIFYobmV0KSR0eXBlID09ICdIaWdoZXIgRWR1Y2F0aW9uJyApXSAKKQojIHVuaV9uZXQKIyBWKHVuaV9uZXQpJHR5cGUgIyDQv9GA0L7QstC10YDRj9C10LwsINGH0YLQviDQstGB0LUg0LLQtdGA0YjQuNC90Ysg0LIg0L3QvtCy0L7QvCDQs9GA0LDRhNC1INCy0YPQt9GLCgplZGdlX2RlbnNpdHkobmV0KSAjIDAuMDAzNzQ1NjAxCmVkZ2VfZGVuc2l0eSh1bmlfbmV0KSAjIDAuMTIwMTk1NwoKZWRnZV9kZW5zaXR5KHVuaV9uZXQpIC8gZWRnZV9kZW5zaXR5KG5ldCkgIyAzMi4wODk4MgpgYGAKCmBgYHtyfQpuX2MgIyA1NApwICMgMC4wMDM3NDU2MDEKbl9uYyA8LSBzdW0oIFYobmV0KSR0eXBlICE9ICdIaWdoZXIgRWR1Y2F0aW9uJyApCm5fbmMgIyAxNDU3CgpleHBfaGV0ZXJvX3VuaSA8LSBuX25jICogbl9jICogcApleHBfaGV0ZXJvX3VuaSAjIDI5NC42OTY0CgptX21peGVkIDwtIDAKCmZvciAocm93IGluIDE6bnJvdyhlZGdlcykpIHsKICBmcm9tX29iaiA8LSBlZGdlc1tyb3csICdmcm9tJ10KICB0b19vYmogPC0gZWRnZXNbcm93LCAndG8nXQogIAogIGlmICggKGZyb21fb2JqICVpbiUgdW5pcykgJiYgISh0b19vYmogJWluJSB1bmlzKSApIHsKICAgIG1fbWl4ZWQgPC0gbV9taXhlZCArIDEKICB9CiAgaWYgKCAhKGZyb21fb2JqICVpbiUgdW5pcykgJiYgKHRvX29iaiAlaW4lIHVuaXMpICkgewogICAgbV9taXhlZCA8LSBtX21peGVkICsgMQogIH0KfQoKbV9taXhlZCAjIDIwNTEKCmhldGVyb3BoaWxpY2l0eV91bmkgPC0gbV9taXhlZCAvIGV4cF9oZXRlcm9fdW5pCmhldGVyb3BoaWxpY2l0eV91bmkgIyA2Ljk1OTcwNgpgYGAKCiMjIyMgYEhpZ2hlciBFZHVjYXRpb25gIHZzIGBCdXNpbmVzcyBFbnRlcnByaXNlYAoKYGBge3J9CiMgdW5pX2Jpel9uZXQgPC0gaW5kdWNlZF9zdWJncmFwaCggCiMgICBuZXQsIAojICAgdj1WKG5ldClbd2hpY2goIAojICAgICAoVihuZXQpJHR5cGUgPT0gJ0hpZ2hlciBFZHVjYXRpb24nKSB8fCAoVihuZXQpJHR5cGUgPT0gJ0J1c2luZXNzIEVudGVycHJpc2UnKSAKIyAgICAgICApXSAKIyApCnVuaV9iaXpfbmV0IDwtIGluZHVjZWRfc3ViZ3JhcGgoIAogIG5ldCwgCiAgdj1WKG5ldClbd2hpY2goIFYobmV0KSR0eXBlICVpbiUgYygnSGlnaGVyIEVkdWNhdGlvbicsICdCdXNpbmVzcyBFbnRlcnByaXNlJykgKV0gCikKIyB1bmlfYml6X25ldAojIFYodW5pX2Jpel9uZXQpJHR5cGUKCnVuaV93b3V0X2Jpel9uZXQgPC0gaW5kdWNlZF9zdWJncmFwaCggCiAgdW5pX2Jpel9uZXQsIAogIHY9Vih1bmlfYml6X25ldClbd2hpY2goIFYodW5pX2Jpel9uZXQpJHR5cGUgPT0gJ0hpZ2hlciBFZHVjYXRpb24nICldIAopCiMgdW5pX3dvdXRfYml6X25ldAojIFYodW5pX3dvdXRfYml6X25ldCkkdHlwZQoKCnBfdW5pX3ZzX2JpeiA8LSBlZGdlX2RlbnNpdHkodW5pX2Jpel9uZXQpCnBfdW5pX3ZzX2JpeiAjIDAuMDAzMDM2MTY1CmVkZ2VfZGVuc2l0eSh1bmlfd291dF9iaXpfbmV0KSAjIDAuMTIwMTk1NwoKZHlhZGljaXR5X3VuaV92c19iaXogPC0gZWRnZV9kZW5zaXR5KHVuaV93b3V0X2Jpel9uZXQpIC8gcF91bmlfdnNfYml6IApkeWFkaWNpdHlfdW5pX3ZzX2JpeiAjIDM5LjU4Nzk5CmBgYAoKYGBge3J9Cm5fYyAjIDU0CnBfdW5pX3ZzX2JpeiAjIDAuMDAzMDM2MTY1Cm5fbmNfYml6IDwtIHN1bSggVihuZXQpJHR5cGUgPT0gJ0J1c2luZXNzIEVudGVycHJpc2UnICkKbl9uY19iaXogIyAxMDEwCgpleHBfaGV0ZXJvX3VuaV92c19iaXogPC0gbl9uY19iaXogKiBuX2MgKiBwX3VuaV92c19iaXoKZXhwX2hldGVyb191bmlfdnNfYml6ICMgMTY1LjU5MjUKCmJpeiA8LSBWKG5ldClbd2hpY2goIFYobmV0KSR0eXBlID09ICdCdXNpbmVzcyBFbnRlcnByaXNlJyApXQpiaXogPC0gbmFtZXMoYml6KQojIGJpegoKbV9taXhlZF92c19iaXogPC0gMAoKZm9yIChyb3cgaW4gMTpucm93KGVkZ2VzKSkgewogIGZyb21fb2JqIDwtIGVkZ2VzW3JvdywgJ2Zyb20nXQogIHRvX29iaiA8LSBlZGdlc1tyb3csICd0byddCiAgCiAgaWYgKCAoZnJvbV9vYmogJWluJSB1bmlzKSAmJiAodG9fb2JqICVpbiUgYml6KSApIHsKICAgIG1fbWl4ZWRfdnNfYml6IDwtIG1fbWl4ZWRfdnNfYml6ICsgMQogIH0KICBpZiAoIChmcm9tX29iaiAlaW4lIGJpeikgJiYgKHRvX29iaiAlaW4lIHVuaXMpICkgewogICAgbV9taXhlZF92c19iaXogPC0gbV9taXhlZF92c19iaXogKyAxCiAgfQp9CgptX21peGVkX3ZzX2JpeiAjIDExMzkKCmhldGVyb3BoaWxpY2l0eV91bmlfdnNfYml6IDwtIG1fbWl4ZWRfdnNfYml6IC8gZXhwX2hldGVyb191bmlfdnNfYml6CmhldGVyb3BoaWxpY2l0eV91bmlfdnNfYml6ICMgNi44NzgzMzMKYGBgCgojIyMjIGBIaWdoZXIgRWR1Y2F0aW9uYCB2cyBgR292ZXJubWVudGAKCmBgYHtyfQp1bmlfZ292X25ldCA8LSBpbmR1Y2VkX3N1YmdyYXBoKCAKICBuZXQsIAogIHY9VihuZXQpW3doaWNoKCBWKG5ldCkkdHlwZSAlaW4lIGMoJ0hpZ2hlciBFZHVjYXRpb24nLCAnR292ZXJubWVudCcpICldIAopCiMgVih1bmlfZ292X25ldCkkdHlwZQoKdW5pX3dvdXRfZ292X25ldCA8LSBpbmR1Y2VkX3N1YmdyYXBoKCAKICB1bmlfZ292X25ldCwgCiAgdj1WKHVuaV9nb3ZfbmV0KVt3aGljaCggVih1bmlfZ292X25ldCkkdHlwZSA9PSAnSGlnaGVyIEVkdWNhdGlvbicgKV0gCikKIyBWKHVuaV93b3V0X2dvdl9uZXQpJHR5cGUKCgpwX3VuaV92c19nb3YgPC0gZWRnZV9kZW5zaXR5KHVuaV9nb3ZfbmV0KSAKcF91bmlfdnNfZ292ICMgMC4wNDIzMTM4MQplZGdlX2RlbnNpdHkodW5pX3dvdXRfZ292X25ldCkgIyAwLjEyMDE5NTcKCmR5YWRpY2l0eV91bmlfdnNfZ292IDwtIGVkZ2VfZGVuc2l0eSh1bmlfd291dF9nb3ZfbmV0KSAvIHBfdW5pX3ZzX2dvdiAKZHlhZGljaXR5X3VuaV92c19nb3YgIyAyLjg0MDU3OApgYGAKCmBgYHtyfQpuX2MgIyA1NApwX3VuaV92c19nb3YgIyAwLjA0MjMxMzgxCm5fbmNfZ292IDwtIHN1bSggVihuZXQpJHR5cGUgPT0gJ0J1c2luZXNzIEVudGVycHJpc2UnICkKbl9uY19nb3YgIyAxMDEwCgpleHBfaGV0ZXJvX3VuaV92c19nb3YgPC0gbl9uY19nb3YgKiBuX2MgKiBwX3VuaV92c19nb3YKZXhwX2hldGVyb191bmlfdnNfZ292ICMgMjMwNy43OTUKCmdvdiA8LSBWKG5ldClbd2hpY2goIFYobmV0KSR0eXBlID09ICdCdXNpbmVzcyBFbnRlcnByaXNlJyApXQpnb3YgPC0gbmFtZXMoZ292KQojIGdvdgoKbV9taXhlZF92c19nb3YgPC0gMAoKZm9yIChyb3cgaW4gMTpucm93KGVkZ2VzKSkgewogIGZyb21fb2JqIDwtIGVkZ2VzW3JvdywgJ2Zyb20nXQogIHRvX29iaiA8LSBlZGdlc1tyb3csICd0byddCiAgCiAgaWYgKCAoZnJvbV9vYmogJWluJSB1bmlzKSAmJiAodG9fb2JqICVpbiUgZ292KSApIHsKICAgIG1fbWl4ZWRfdnNfZ292IDwtIG1fbWl4ZWRfdnNfZ292ICsgMQogIH0KICBpZiAoIChmcm9tX29iaiAlaW4lIGdvdikgJiYgKHRvX29iaiAlaW4lIHVuaXMpICkgewogICAgbV9taXhlZF92c19nb3YgPC0gbV9taXhlZF92c19nb3YgKyAxCiAgfQp9CgptX21peGVkX3ZzX2dvdiAjIDAuNDkzNTQ0NwoKaGV0ZXJvcGhpbGljaXR5X3VuaV92c19nb3YgPC0gbV9taXhlZF92c19nb3YgLyBleHBfaGV0ZXJvX3VuaV92c19nb3YKaGV0ZXJvcGhpbGljaXR5X3VuaV92c19nb3YgIyAwLjQ5MzU0NDcKYGBgCgrQodC+0LHQtdGA0LXQvCDQv9C+0LvRg9GH0LXQvdC90YvQtSDQt9C90LDRh9C10L3QuNGPICpkeWFkaWNpdHkqINC4ICpoZXRlcm9waGlsaWNpdHkqINCy0LzQtdGB0YLQtTogLSBgSGlnaGVyIEVkdWNhdGlvbmAgdnMg0LLRgdC1INC+0YHRgtCw0LvRjNC90YvQtTogLSBkeWFkaWNpdHk6IGByIGRpYWRpY2l0eV91bmkgIyAzMi4wODk4MmAgLSBoZXRlcm9waGlsaWNpdHk6IGByIGhldGVyb3BoaWxpY2l0eV91bmkgIyA2Ljk1OTcwNmAgLSBgSGlnaGVyIEVkdWNhdGlvbmAgdnMgYEJ1c2luZXNzIEVudGVycHJpc2VgOiAtIGR5YWRpY2l0eTogYHIgZHlhZGljaXR5X3VuaV92c19iaXogIyAzOS41ODc5OWAgLSBoZXRlcm9waGlsaWNpdHk6IGByIGhldGVyb3BoaWxpY2l0eV91bmlfdnNfYml6ICMgNi44NzgzMzNgIC0gYEhpZ2hlciBFZHVjYXRpb25gIHZzIGBHb3Zlcm5tZW50YDogLSBkeWFkaWNpdHk6IGByIGR5YWRpY2l0eV91bmlfdnNfZ292ICMgMi44NDA1NzhgIC0gaGV0ZXJvcGhpbGljaXR5OiBgciBoZXRlcm9waGlsaWNpdHlfdW5pX3ZzX2dvdiAjIDAuNDkzNTQ0N2AuCgrQnNGLINCy0LjQtNC40LwsINGH0YLQviBkeWFkaWNpdHkg0YPQvdC40LLQtdGA0YHQuNGC0LXRgtC+0LIg0L/RgNC4INGA0LDQt9C00LXQu9C10L3QuNC4INC90LAg0YPQvdC40LLQtdGA0YHQuNGC0LXRgtGLINC4INCy0YHQtdGFINC+0YHRgtCw0LvRjNC90YvRhSAo0LAg0YLQsNC60LbQtSDQv9GA0Lgg0YDQsNC30LTQtdC70LXQvdC40Lgg0L3QsCDRg9C90LjQstC10YDRgdC40YLQtdGC0Ysg0Lgg0LHQuNC30L3QtdGBKSDQvtGH0LXQvdGMINCy0YvRgdC+0LrQsNGPLiDQn9GA0Lgg0Y3RgtC+0LwgaGV0ZXJvcGhpbGljaXR5INGC0LDQutC20LUg0LTQvtCy0L7Qu9C70YzQvdC+INGB0LjQu9GM0L3QviDQv9GA0LXQstGL0YjQsNC10YIgMS4KCtCSINGH0LXQvCDQvNC+0LbQtdGCINCx0YvRgtGMINC+0LHRitGP0YHQvdC10L3QuNC1INGN0YLQvtC5INC+0YHQvtCx0LXQvdC90L7RgdGC0Lgg0LTQsNC90L3Ri9GFPyDQmtCw0Log0YPRgtCy0LXRgNC20LTQsNC10YLRgdGPINCyINGB0YLQsNGC0YzQtSBbIkZ1bmN0aW9uYWwgZHlhZGljaXR5IGFuZCBoZXRlcm9waGlsaWNpdHkgb2YgZ2VuZS1nZW5lIGludGVyYWN0aW9ucyBpbiBzdGF0aXN0aWNhbCBlcGlzdGFzaXMgbmV0d29ya3MiXShodHRwczovL2Jpb2RhdGFtaW5pbmcuYmlvbWVkY2VudHJhbC5jb20vYXJ0aWNsZXMvMTAuMTE4Ni9zMTMwNDAtMDE1LTAwNjItNCksINC+0L/QuNGB0LDQvdC90YvQuSDQstGL0YjQtSDRhNCw0LrRgiDQvNC+0LbQtdGCINCx0YvRgtGMINGB0LLRj9C30LDQvSDRgSDRgtC10LwsINGH0YLQviDQstC10YDRiNC40L3RiyDRgdC+INC30L3QsNGH0LXQvdC40LXQvCDQvNC10YLQutC4IGAxYCDQuNC80LXRjtGCINCx0L7Qu9GM0YjRg9GOINGG0LXQvdGC0YDQsNC70YzQvdC+0YHRgtGMICRcUmlnaHRhcnJvdyQg0YXQvtGA0L7RiNC+INGB0LLRj9C30LDQvdGLINC00YDRg9CzINGBINC00YDRg9Cz0L7QvCDQuCDRgSDQstC10YDRiNC40L3QsNC80Lgg0LTRgNGD0LPQvtCz0L4g0YLQuNC/0LAuCgrQkiAq0JfQsNC00LDQvdC40LggNiog0LzRiyDQsdGD0LTQtdC8INC/0YDQvtCy0LXRgNGP0YLRjCDQs9C40L/QvtGC0LXQt9GDINC60LDRgdCw0YLQtdC70YzQvdC+INCy0YvRgdC+0LrQuNGFINGB0YLQtdC/0LXQvdC10Lkg0LLQtdGA0YjQuNC9INGC0LjQv9CwIGBIaWdoZXIgRWR1Y2F0aW9uYCDRgdGA0LXQtNC4INC60YDRg9C/0L3Ri9GFINGD0L3QuNCy0LXRgNGB0LjRgtC10YLQvtCyLgoKIyMjIyDQktGL0LLQvtC00YsKCioq0JLRi9Cy0L7QtNGLINC/0L4g0JfQsNC00LDQvdC40Y4gNDoqKiDQnNGLINC/0L7Qu9GD0YfQuNC70LgsINGH0YLQviDQvdC10YHQvNC+0YLRgNGPINC90LAg0L/Qu9C+0YLQvdGL0LUg0YHQstGP0LfQuCDRg9GH0YDQtdC20LTQtdC90LjQuSDQstGL0YHRiNC10LPQviDQvtCx0YDQsNC30L7QstCw0L3QuNGPINC80LXQttC00YMg0YHQvtCx0L7QuSwg0L/QviDQutGA0LDQudC90LXQuSDQvNC10YDQtSDQvdC10LrQvtGC0L7RgNGL0LUg0LjQtyDQvdC40YUg0LjQvNC10Y7RgiDRgtCw0LrQttC1INC/0YDQvtGH0L3Ri9C1INGB0LLRj9C30Lgg0YEg0LTRgNGD0LPQuNC80Lgg0YLQuNC/0LDQvNC4INC+0YDQs9Cw0L3QuNC30LDRhtC40LkgKNCyINGH0LDRgdGC0L3QvtGB0YLQuCDRgSDQsdC40LfQvdC10YHQvtC8KS4KCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMjINCX0LDQtNCw0L3QuNC1IDUKCtCf0YDQvtCy0LXQtNC10Lwg0L/RgNC+0YbQtdC00YPRgNGDINC60LvQsNGB0YLQtdGA0LjQt9Cw0YbQuNC4INCy0LXRgNGI0LjQvSDQv9GA0Lgg0L/QvtC80L7RidC4IEVkZ2UtYmV0d2Vlbm5lc3Mg0LggRmFzdC1ncmVlZHkg0LzQtdGC0L7QtNC+0LIg0Lgg0YHRgNCw0LLQvdC40Lwg0L/QvtC70YPRh9C10L3QvdGL0LUg0YDQtdC30YPQu9GM0YLQsNGC0Ysg0YEg0YHRg9GJ0LXRgdGC0LLRg9GO0YnQtdC5INC60LvQsNGB0YHQuNGE0LjQutCw0YbQuNC10LkuCgrQoi7Qui4g0YHRh9C40YLQsNGC0Ywg0LrRgNCw0YLRh9Cw0LnRiNC40Lkg0L/Rg9GC0Ywg0LTQu9GPINC40YHRhdC+0LTQvdGL0YUg0LLQtdGB0L7QsiDRgNC10LHQtdGAINGP0LLQu9GP0LXRgtGB0Y8g0L3QtSDQvtGH0LXQvdGMINC+0YHQvNGL0YHQu9C10L3QvdGL0LwsINC40YHQv9C+0LvRjNC30YPQtdC8INC+0LHRgNCw0YLQvdGL0LUg0LTQu9GPINC40YHRhdC+0LTQvdGL0YUg0LLQtdGB0LAg0YDQtdCx0LXRgC4KCtCX0LDQvNC10YfQsNC90LjQtTog0JTQu9GPIEZhc3QtZ3JlZWR5INC90LUg0LLQsNC20L3Qviwg0LrQsNC60LjQtSDQtNCw0L3QvdGL0LUg0LjRgdC/0L7Qu9GM0LfQvtCy0LDRgtGMOiDQuNGB0YXQvtC00L3Ri9C1INC40LvQuCDQuNC90LLQtdGA0YLQuNGA0L7QstCw0L3QvdGL0LUsINGCLtC6LiDRjdGC0L7RgiDQvNC10YLQvtC0INC90LUg0YPRh9C40YLRi9Cy0LDQtdGCINCy0LXRgdCwINGA0LXQsdC10YAgKNGC0L7Qu9GM0LrQviDQuNGFINC60L7Qu9C40YfQtdGB0YLQstC+KS4KCmBgYHtyfQojINC/0YDQvtCy0L7QtNC40Lwg0LrQu9Cw0YHRgtC10YDQuNC30LDRhtC40Y4g0L/RgNC4INC/0L7QvNC+0YnQuCDQvNC10YLQvtC00LAgRWRnZS1iZXR3ZWVubmVzcwpjZWIgPC0gY2x1c3Rlcl9lZGdlX2JldHdlZW5uZXNzKG5ldCwgd2VpZ2h0cz1FKG5ldCkkd2VpZ2h0KQoKIyDRgdC80L7RgtGA0LjQvCDQvdCwINC/0L7Qu9GD0YfQtdC90L3Ri9C1INCyINGA0LXQt9GD0LvRjNGC0LDRgtC1INC60LvQsNGB0YLQtdGA0LjQt9Cw0YbQuNC4INC+0LHRitC10LrRgtGLCm1ic2hpcF9jZWIgPC0gbWVtYmVyc2hpcChjZWIpIAojIG1ic2hpcF9jZWIKCnNfY2ViIDwtIHNpemVzKGNlYikKc19jZWIKCm1zX2NlYiA8LSBtb2R1bGFyaXR5KGNlYikKbXNfY2ViICMgMC41MjcyNjIKYGBgCgpgYGB7cn0KIyBjZWIKYGBgCgpgYGB7cn0KIyA+IHNfY2ViIDwtIHNpemVzKGNlYikKIyA+IHNfY2ViCiMgQ29tbXVuaXR5IHNpemVzCiMgICAxICAgMiAgIDMgICA0ICAgNSAgIDYgICA3ICAgOCAgIDkgIDEwICAxMSAgMTIgIDEzICAxNCAgMTUgIDE2ICAxNyAgMTggIDE5ICAyMCAKIyAgNDUgMjEzIDIzMyAxNTQgMjI5IDE5MCAgNzUgIDQ2IDE2NCAgNDggIDMyICAgMiAgIDIgICAyICAgMyAgMTUgICAyICAgMiAgIDggICAyIAojICAyMSAgMjIgIDIzICAyNCAgMjUgIDI2ICAyNyAgMjggIDI5ICAzMCAgMzEgIDMyICAzMyAgMzQgIDM1ICAzNiAgMzcgIDM4IAojICAgMiAgIDQgICAyICAgMiAgIDIgICAyICAgNyAgIDIgICAyICAgMiAgIDIgICAyICAgMiAgIDIgICAyICAgMiAgIDMgICAyIApgYGAKCmBgYHtyfQojID4gbXNfY2ViIDwtIG1vZHVsYXJpdHkoY2ViKQojID4gbXNfY2ViCiMgWzFdIDAuNTI3MjYyCmBgYAoKKirQktC40LfRg9Cw0LvQuNC30LDRhtC40Y8g0LrQu9Cw0YHRgtC10YDQuNC30LDRhtC40Lgg0LzQtdGC0L7QtNC+0LwgRWRnZS1iZXR3ZWVubmVzczoqKgoKYGBge3J9CnBsb3QoCiAgY2ViLCBuZXQsIAogIHZlcnRleC5sYWJlbD1OQSwgCiAgdmVydGV4LmNvbG9yPVYobmV0KSRjb2xvciwgCiAgbGF5b3V0PWxheW91dF9uaWNlbHkKKQpgYGAKCmBgYHtyfQpwbG90KAogIGNlYiwgbmV0LCAKICB2ZXJ0ZXgubGFiZWw9TkEsIAogIHZlcnRleC5jb2xvcj1WKG5ldCkkY29sb3IsIAogIGxheW91dD1sYXlvdXRfd2l0aF9sZ2wKKQpgYGAKCioq0KHRgNCw0LLQvdC40Lwg0YDQtdC30YPQu9GM0YLQsNGC0Ysg0LrQu9Cw0YHRgtC10YDQuNC30LDRhtC40LggRWRnZS1iZXR3ZWVubmVzcyDQuCDQuNC80LXRjtGJ0YPRjtGB0Y8g0LrQu9Cw0YHRgdC40YTQuNC60LDRhtC40Y4g0LLQtdGA0YjQuNC9OioqCgpgYGB7cn0KY29tcGFyZShjZWIsIFYobmV0KSR0eXBlLCBtZXRob2Q9J25taScpICMgCiMg0LfQtNC10YHRjCDQuCDQtNCw0LvQtdC1INC80Ysg0LjRgdC/0L7Qu9GM0LfRg9C10Lwg0L3QvtGA0LzQsNC70LjQt9C+0LLQsNC90L3QvtC1INC30L3QsNGH0LXQvdC40LUg0YTRg9C90LrRhtC40LggY29tcGFyZSgpINC00LvRjyDQvtCx0LvQtdCz0YfQtdC90LjRjyDQuNC90YLQtdGA0L/RgNC10YLQsNGG0LjQuCDQstC+0LfQstGA0LDRidCw0LXQvNC+0LPQviDRgNC10LfRg9C70YzRgtCw0YLQsApgYGAKCtCi0LDQutC40Lwg0L7QsdGA0LDQt9C+0LwsINC80Ysg0LLQuNC00LjQvCwg0YfRgtC+INC40LzQtdGO0YnQsNGP0YHRjyDQutC70LDRgdGB0LjRhNC40LrQsNGG0LjRjyDQstC10YDRiNC40L0g0YHQvtCy0YHQtdC8INC90LUg0L/QvtGF0L7QttCwINC90LAg0YLQviwg0YfRgtC+INC80Ysg0L/QvtC70YPRh9C40LvQuCDQv9GA0Lgg0LrQu9Cw0YHRgtC10YDQuNC30LDRhtC40LguIDxtYXJrPiDQn9C+INCy0YHQtdC5INCy0LjQtNC40LzQvtGB0YLQuCwgItGA0LDQt9C00LXQu9C10L3QuNC1INC/0L4g0LHRg9GC0YvQu9C+0YfQvdC+0LzRgyDQs9C+0YDQu9GL0YjQutGDIiDRj9Cy0LvRj9C10YLRgdGPINC90LUg0L7Rh9C10L3RjCDRhdC+0YDQvtGI0LjQvCDRgdC/0L7RgdC+0LHQvtC8INC00LvRjyDQutC70LDRgdGC0LXRgNC40LfQsNGG0LjQuCDQstC10YDRiNC40L0g0LIg0L3QsNGI0LXQvCDQtNCw0YLQsNGB0LXRgtC1LiA8L21hcms+CgpgYGB7cn0KIyDQv9GA0L7QstC+0LTQuNC8INC60LvQsNGB0YLQtdGA0LjQt9Cw0YbQuNGOINC/0YDQuCDQv9C+0LzQvtGJ0Lgg0LzQtdGC0L7QtNCwIEZhc3QtZ3JlZWR5CmNmZyA8LSBjbHVzdGVyX2Zhc3RfZ3JlZWR5KG5ldCwgd2VpZ2h0cz1FKG5ldCkkd2VpZ2h0KSAKCiMg0YHQvNC+0YLRgNC40Lwg0L3QsCDQv9C+0LvRg9GH0LXQvdC90YvQtSDQsiDRgNC10LfRg9C70YzRgtCw0YLQtSDQutC70LDRgdGC0LXRgNC40LfQsNGG0LjQuCDQvtCx0YrQtdC60YLRiwptYnNoaXBfY2ZnIDwtIG1lbWJlcnNoaXAoY2ZnKSAKIyBtYnNoaXBfY2ZnCgpzX2NmZyA8LSBzaXplcyhjZmcpCnNfY2ZnCgptc19jZmcgPC0gbW9kdWxhcml0eShjZmcpCm1zX2NmZyAjIDAuNTMxMDA1NQpgYGAKCmBgYHtyfQojIGNmZwpgYGAKCmBgYHtyfQojID4gc19jZmcgPC0gc2l6ZXMoY2ZnKQojID4gc19jZmcKIyBDb21tdW5pdHkgc2l6ZXMKIyAgIDEgICAyICAgMyAgIDQgICA1ICAgNiAgIDcgICA4ICAgOSAgMTAgIDExICAxMiAgMTMgIDE0ICAxNSAgMTYgIDE3ICAxOCAgMTkgIDIwICAyMSAgMjIgIDIzICAyNCAgMjUgIDI2IAojIDIxOSAxNDQgMjEyIDEzMiAxNDEgIDk0IDE4OSAxMjAgIDg0ICA4MiAgMjggICAzICAgMiAgMTUgICAzICAgMyAgIDIgICAyICAgMiAgIDIgICAyICAgMiAgIDIgICAyICAgMiAgIDIgCiMgIDI3ICAyOCAgMjkgIDMwICAzMSAgMzIgIDMzICAzNCAgMzUgIDM2IAojICAgMiAgIDIgICAyICAgMiAgIDIgICAyICAgMiAgIDIgICAyICAgMiAKYGBgCgpgYGB7cn0KIyA+IG1zX2NmZyA8LSBtb2R1bGFyaXR5KGNmZykKIyA+IG1zX2NmZwojIFsxXSAwLjUzMTAwNTUKYGBgCgoqKtCS0LjQt9GD0LDQu9C40LfQsNGG0LjRjyDQutC70LDRgdGC0LXRgNC40LfQsNGG0LjQuCDQvNC10YLQvtC00L7QvCBGYXN0LWdyZWVkeToqKgoKYGBge3J9CnBsb3QoCiAgY2ZnLCBuZXQsIAogIHZlcnRleC5sYWJlbD1OQSwgCiAgdmVydGV4LmNvbG9yPVYobmV0KSRjb2xvciwgCiAgbGF5b3V0PWxheW91dF9uaWNlbHkKKQpgYGAKCmBgYHtyfQpwbG90KAogIGNmZywgbmV0LCAKICB2ZXJ0ZXgubGFiZWw9TkEsIAogIHZlcnRleC5jb2xvcj1WKG5ldCkkY29sb3IsIAogIGxheW91dD1sYXlvdXRfd2l0aF9sZ2wKKQpgYGAKCmBgYHtyfQpjb21wYXJlKGNmZywgVihuZXQpJHR5cGUsIG1ldGhvZD0nbm1pJykgIyAwLjAzMzg2NTExCmBgYAoK0KLQsNC60LjQvCDQvtCx0YDQsNC30L7QvCwg0LzRiyDQstC40LTQuNC8LCDRh9GC0L4g0YLQsNC6INC20LUsINC60LDQuiDQuCDQv9GA0LXQtNGL0LTRg9GJ0LjQuSDRgdC/0L7RgdC+0LEg0LrQu9Cw0YHRgtC10YDQuNC30LDRhtC40LgsIEZhc3QtZ3JlZWR5INC90LUg0L7Rh9C10L3RjCDRhdC+0YDQvtGI0L4g0YHQvtC+0YLQstC10YLRgdGC0LLRg9C10YIg0YDQtdCw0LvRjNC90L7QuSDQutC70LDRgdGB0LjRhNC40LrQsNGG0LjQuCDRgNCw0YHRgdC80LDRgtGA0LjQstCw0LXQvNGL0YUg0LjQvdGB0YLQuNGC0YPRgtC+0LIuCgojIyMjINCS0YvQstC+0LTRiwoKKirQktGL0LLQvtC0INC/0L4g0JfQsNC00LDQvdC40Y4gNToqKiDQmNC30LLQtdGB0YLQvdGL0LUg0L3QsNC8INGB0L/QvtGB0L7QsdGLINC60LvQsNGB0YLQtdGA0LjQt9Cw0YbQuNC4IChFZGdlLWJldHdlZW5uZXNzINC4IEZhc3QtZ3JlZWR5KSDQvdC1INC00LDQu9C4INGA0LXQt9GD0LvRjNGC0LDRgtCwLCDQv9C+0YXQvtC20LXQs9C+INC90LAg0LjQvNC10Y7RidGD0Y7RgdGPINCyINC00LDRgtCw0YHQtdGC0LUg0LrQu9Cw0YHRgdC40YTQuNC60LDRhtC40Y4uCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIyDQl9Cw0LTQsNC90LjQtSA2CgrQmNC30L3QsNGH0LDQu9GM0L3QviDQsdGL0Lsg0L/QvtGB0YLQsNCy0LvQtdC9INC40YHRgdC70LXQtNC+0LLQsNGC0LXQu9GM0YHQutC40Lkg0LLQvtC/0YDQvtGBLCDQvdCw0YHQutC+0LvRjNC60L4g0LDQutGC0LjQstC90L4g0L/RgNC4INC90LDQv9C40YHQsNC90LjQuCDQvdCw0YPRh9C90YvRhSDRgNCw0LHQvtGCINGD0L3QuNCy0LXRgNGB0LjRgtC10YLRiyDQndC+0LLQvtC5INCX0LXQu9Cw0L3QtNC40Lgg0LLQt9Cw0LjQvNC+0LTQtdC50YHRgtCy0YPRjtGCINGBINC00YDRg9Cz0LjQvNC4INGC0LjQv9Cw0LzQuCDQvtGA0LPQsNC90LjQt9Cw0YbQuNC5LCDQvdGD0LbQvdC+INC70Lgg0LjQvCDQutCw0Lot0YLQviDQsiDRjdGC0L7QvCDRgdC/0L7RgdC+0LHRgdGC0L7QstCw0YLRjCDQuNC30LLQvdC1ICjQvdCw0L/RgNC40LzQtdGALCDRgdC+0LfQtNCw0LLQsNGC0Ywg0L7QsdGJ0LjQtSDQu9Cw0LHQvtGC0LDRgNC40Lgg0YEg0LjQvdC00YPRgdGC0YDQuNCw0LvRjNC90YvQvNC4INC60L7RgNC/0L7RgNCw0YbQuNGP0LzQuCDQuCDQs9C+0YHRg9C00LDRgNGB0YLQstC10L3QvdGL0LzQuCDQvtGA0LPQsNC90LDQvNC4KS4g0J/QvtC80LjQvNC+INGA0LDRgdGH0LXRgtCwINC30L3QsNGH0LXQvdC40Lkg0LPQvtC80L7RhNC40LvQuNC4INC4INGA0LDQt9C70LjRh9C90YvRhSDQstC40LTQvtCyINGG0LXQvdGC0YDQsNC70YzQvdC+0YHRgtC10LksINC00LvRjyDQvtGC0LLQtdGC0LAg0L3QsCDQt9Cw0LTQsNC90L3Ri9C5INCy0L7Qv9GA0L7RgSDQvdCw0Lwg0LzQvtC20LXRgiDQv9C+0LzQvtGH0Ywg0LzQvtC00LXQu9GMINC/0YDQtdC00YHQutCw0LfQsNC90LjRjyDQutC70LDRgdGB0LAg0LLQtdGA0YjQuNC9ICpSZWxhdGlvbmFsIE5laWdoYm9ycyBDbGFzc2lmaWVyKiAoKlJOQyopLgoK0KDQsNC30LTQtdC70LjQvCDQstGB0LUg0LLQtdGA0YjQuNC90Ysg0L3QsCAyINC60LvQsNGB0YHQsDogIjEiIC0g0YPQvdC40LLQtdGA0YHQuNGC0LXRgiwgIjAiIC0g0LjQvdCw0YfQtS4g0J7RgtCx0LXRgNC10Lwg0LjQtyDQutCw0LbQtNC+0LPQviDQutC70LDRgdGB0LAg0L/QviAxMCDQstC10YDRiNC40L0g0Lgg0L/QvtC70L7QttC40Lwg0LLQtdGA0L7Rj9GC0L3QvtGB0YLQuCDQuNGFINC/0YDQuNC90LDQtNC70LXQttC90L7RgdGC0Lgg0L/QtdGA0LLQvtC80YMg0LrQu9Cw0YHRgdGDINGB0L7QvtGC0LLQtdGC0YHRgtCy0LXQvdC90L4gYDFgINC4IGAwYC4g0JTQu9GPINCy0YHQtdGFINC+0YHRgtCw0LvRjNC90YvRhSDQstC10YDRiNC40L0gKGB1bmtub3duYCkg0L/QvtC70L7QttC40Lwg0Y3RgtGDINCy0LXRgNC+0Y/RgtC90L7RgdGC0Ywg0YDQsNCy0L3QvtC5IGAwLjVgLiDQn9GA0Lgg0LrQsNC20LTQvtC5INC40YLQtdGA0LDRhtC40Lgg0LHRg9C00LXQvCDQvtCx0L3QvtCy0LvRj9GC0Ywg0LLQtdGA0L7Rj9GC0L3QvtGB0YLQuCDQutCw0LbQtNC+0Lkg0LLQtdGA0YjQuNC90Ysg0LjRgdGF0L7QtNGPINC40Lcg0LLQtdGA0L7Rj9GC0L3QvtGB0YLQtdC5INC10ZEg0YHQvtGB0LXQtNC10LkuINCSINC40YLQvtCz0LUsINC/0L7RgdC70LUgMTAg0YLQsNC60LjRhSDQuNGC0LXRgNCw0YbQuNC5INC/0L7Qu9GD0YfQuNC8INC00LvRjyDQutCw0LbQtNC+0Lkg0LLQtdGA0YjQuNC90Ysg0LLQtdGA0L7Rj9GC0L3QvtGB0YLRjCDQtdGRINC/0YDQuNC90LDQtNC70LXQttC90L7RgdGC0Lgg0LrQu9Cw0YHRgdGDICIxIiwg0Lgg0L7RgtCx0LXRgNC10Lwg0YLQtSDQstC10YDRiNC40L3Riywg0YfRjNGPINCy0LXRgNC+0Y/RgtC90L7RgdGC0Ywg0LHQvtC70YzRiNC1INC/0L7RgNC+0LPQsCBgMC41YCDQsiDQutCw0YfQtdGB0YLQstC1INC/0YDQuNC90LDQtNC70LXQttCw0YnQuNGFINC60LvQsNGB0YHRgyAiMSIuCgrQlNC70Y8g0LjQt9Cx0LXQttCw0L3QuNGPINGB0LvRg9GH0LDQudC90L7RgdGC0Lgg0L/QvtCy0YLQvtGA0LjQvCDRjdGC0L7RgiDQsNC70LPQvtGA0LjRgtC8IDEwMCDRgNCw0Lcg0Lgg0L/QvtGB0YLRgNC+0LjQvCDQs9C40YHRgtC+0LPRgNCw0LzQvNGDINGA0LDRgdC/0YDQtdC00LXQu9C10L3QuNGPINGH0LjRgdC70LAg0L/RgNC10LTRgdC60LDQt9Cw0L3QvdGL0YUg0YPQvdC40LLQtdGA0YHQuNGC0LXRgtC+0LIsINCwINGC0LDQutC20LUg0LPQuNGB0YLQvtCz0YDQsNC80LzRgyDRgNCw0YHQv9GA0LXQtNC10LvQtdC90LjRjyDRgdGA0LXQtNC90LjRhSDQstC10YDQvtGP0YLQvdC+0YHRgtC10Lkg0L/RgNC40L3QsNC00LvQtdC20L3QvtGB0YLQuCDQs9GA0YPQv9C/0LUg0YPQvdC40LLQtdGA0YHQuNGC0LXRgtC+0LIuCgpgYGB7cn0KcmVzIDwtIHJlcChOQSwgMjApCnByIDwtIHJlcChOQSwgMjApCgpmb3IgKGogaW4gMToyMCl7IAogIG5ldHdvcmsgPC0gbmV0CiAgVihuZXR3b3JrKVt3aGljaCggVihuZXR3b3JrKSR0eXBlID09ICdIaWdoZXIgRWR1Y2F0aW9uJyApXSR0eXBlID0gMQogIFYobmV0d29yaylbd2hpY2goVihuZXR3b3JrKSR0eXBlICE9IDEpXSR0eXBlID0gMAogIAogIAogICMg0LLQtdGA0L7Rj9GC0L3QvtGB0YLRjCDQstC10YDRiNC40L3RiyDQv9C10YDQtdC50YLQuCDQsiDQutC70LDRgdGBIGNodXJuID0gMSDRgNCw0LLQvdCwINC00L7Qu9C1INGB0L7RgdC10LTQtdC5IGNodXJuID0gMSDQvtGCINC+0LHRidC10LPQviDRh9C40YHQu9CwINGB0L7RgdC10LTQtdC5CiAgIyDQuNGB0L/QvtC70YzQt9GD0LXQvCDQvNCw0YLRgNC40YfQvdGL0LUg0LLRi9GH0LjRgdC70LXQvdC40Y8KICByYW5kb21fdW5pIDwtIHNhbXBsZSggVihuZXR3b3JrKVsgd2hpY2goVihuZXR3b3JrKSR0eXBlID09IDEpIF0sIDEwICkKICByYW5kb21fbm90X3VuaSA8LSBzYW1wbGUoIFYobmV0d29yaylbIHdoaWNoKFYobmV0d29yaykkdHlwZSA9PSAwKSBdLCAxMCApCiAgCiAgCiAgZm9yIChpIGluIDE6MTUxMSl7CiAgICBpZiAoIShWKG5ldHdvcmspW2ldICVpbiUgcmFuZG9tX3VuaSB8IChWKG5ldHdvcmspW2ldICVpbiUgcmFuZG9tX25vdF91bmkpKSl7CiAgICAgIFYobmV0d29yaykkdHlwZVtpXSA9IDAuNQogICAgfQogIH0KICAKICBVbmlQcm9iIDwtICBhcy5udW1lcmljKFYobmV0d29yaykkdHlwZSkKICB0aHJlc2hvbGQgPC0gMC41CiAgQSA8LSBhc19hZGphY2VuY3lfbWF0cml4KG5ldHdvcmspCiAgQSA8LSBhcy5tYXRyaXgoQSkKICBOZWlnaGJvcnMgPC0gcm93U3VtcyhBKSAjINC+0LHRidC10LUg0YfQuNGB0LvQviDRgdC+0YHQtdC00LXQuSDQstC10YDRiNC40L3RiwogIAogIFVuaVByb2JfaXRlciA8LSBVbmlQcm9iCiAgZm9yKGkgaW4gMToxMCl7CiAgICBVbmlQcm9iX2l0ZXIgPC0gYXMudmVjdG9yKChBICUqJSBVbmlQcm9iX2l0ZXIpIC8gTmVpZ2hib3JzKQogIH0KICByZXNbal0gPC0gbGVuZ3RoKHdoaWNoKFVuaVByb2JfaXRlciA+IHRocmVzaG9sZCkpCiAgcHJbal0gPC0gbWVhbihVbmlQcm9iX2l0ZXIpCn0KYGBgCgpgYGB7cn0KaGlzdChyZXMsIG1haW49J9Cn0LjRgdC70L4g0L/RgNC10LTRgdC60LDQt9Cw0L3QvdGL0YUg0YPQvdC40LLQtdGA0YHQuNGC0LXRgtC+0LInKQpoaXN0KHByLCBtYWluPSfQodGA0LXQtNC90Y/RjyDQstC10YDQvtGP0YLQvdC+0YHRgtGMINC/0YDQuNC90LDQtNC70LXQttC90L7RgdGC0Lgg0LrQu9Cw0YHRgdGDIDEnKQpgYGAKCtCa0LDQuiDQvNC+0LbQvdC+INGD0LLQuNC00LXRgtGMLCDQv9C+0YfRgtC4INCy0L4g0LLRgdC10YUg0YHQu9GD0YfQsNGP0YUg0LDQsdGB0L7Qu9GO0YLQvdC+0LUg0YfQuNGB0LvQviDQstC10YDRiNC40L0g0L/RgNC10LTRgdC60LDQt9Cw0L1qINCyINC60LDRh9C10YHRgtCy0LUg0YPQvdC40LLQtdGA0YHQuNGC0LXRgtC+0LIuINCf0L7Qu9GD0YfQsNC10LwsINGH0YLQviAq0LrQsNC60LjQtSDQsdGLIDEwINGD0L3QuNCy0LXRgNGB0LjRgtC10YLQvtCyINC80Ysg0L3QuCDQstC30Y/Qu9C4LCDQuNGFINC60LvQsNGB0YEg0LTQvtC50LTQtdGCINC00L4g0LHQvtC70YzRiNC40L3RgdGC0LLQsCDQstC10YDRiNC40L0g0LHRi9GB0YLRgNC10LUsINGH0LXQvCDQv9GA0L7RgtC40LLQvtC/0L7Qu9C+0LbQvdGL0Lkg0LrQu9Cw0YHRgSAxMCDRgdC70YPRh9Cw0LnQvdGL0YUg0LLQtdGA0YjQuNC9Ki4g0K3RgtC+INGA0LDRgdC/0YDQvtGB0YLRgNCw0L3Rj9C10YLRgdGPINC4INC90LAg0YHQu9GD0YfQsNC5LCDQutC+0LPQtNCwINCx0YvQu9C4INCy0YvQsdGA0LDQvdGLINC90LDQuNC80LXQvdC10LUg0YbQtdC90YLRgNCw0LvRjNC90YvQtSDRg9C90LjQstC10YDRgdC40YLQtdGC0YsuINCV0YHQu9C4INCx0Ysg0YPQvdC40LLQtdGA0YHQuNGC0LXRgtGLINCx0YvQu9C4INC/0LvQvtGF0L4g0YHQstGP0LfQsNC90Ysg0YEg0L7RgNCz0LDQvdC40LfQsNGG0LjRj9C80Lgg0LTRgNGD0LPQvtCz0L4g0YLQuNC/0LAsINGC0L4g0LjRhSDQutC70LDRgdGBINC90LDQvNC90L7Qs9C+INGB0LvQsNCx0LXQtSDRgNCw0YHQv9GA0L7RgdGC0YDQsNC90Y/Qu9GB0Y8g0LHRiyDQvdCwINCy0LXRgNGI0LjQvdGLINC00YDRg9Cz0L7Qs9C+INGC0LjQv9CwLCDQsCDRjdGC0L4g0L3QtSDRgtCw0LouCgrQl9C90LDRh9C40YIsINC/0L4g0LrRgNCw0LnQvdC10Lkg0LzQtdGA0LUg0LrQsNC60LjQtS3RgtC+INGD0L3QuNCy0LXRgNGB0LjRgtC10YLRiyAo0LAg0LjQvNC10L3QvdC+INC90LDQuNCx0L7Qu9C10LUg0YbQtdC90YLRgNCw0LvRjNC90YvQtSkg0LTQvtCy0L7Qu9GM0L3QviDQsNC60YLQuNCy0L3QviDQutC+0L7Qv9C10YDQuNGA0YPRjtGC0YHRjyDRgSDQtNGA0YPQs9C40LzQuCDQvtGA0LPQsNC90LjQt9Cw0YbQuNGP0LzQuCAo0LrQsNC6LCDQvdCw0L/RgNC40LzQtdGALCDRjdGC0L4g0LTQtdC70LDQtdGCINCe0LrQu9C10L3QtNGB0LrQuNC5INGD0L3QuNCy0LXRgNGB0LjRgtC10YIpLiDQn9C+0Y3RgtC+0LzRgyDQtNC70Y8g0YLQsNC60LjRhSDRg9C90LjQstC10YDRgdC40YLQtdGC0L7QsiDQvdC10YIg0L3QtdC+0LHRhdC+0LTQuNC80L7RgdGC0Lgg0YHRgtGA0L7QuNGC0Ywg0YHQvtCy0LzQtdGB0YLQvdGL0LUg0YEg0LHQuNC30L3QtdGB0L7QvCDQuCDQs9C+0YHRg9C00LDRgNGB0YLQstC+0Lwg0L3QsNGD0YfQvdGL0LUg0YbQtdC90YLRgNGLLgoK0JLRgdC/0L7QvNC90LjQvCDQv9GA0L4g0LLRi9GB0L7QutC40Lkg0L/QvtC60LDQt9Cw0YLQtdC70YwgKmR5YWRpY2l0eSog0YMg0JLQo9CX0L7Qsjog0LLRi9GF0L7QtNC40YIsINGH0YLQviDQvtC9INC/0L7Qu9GD0YfQsNC10YLRgdGPINGC0LDQutC40Lwg0LHQvtC70YzRiNC40Lwg0LjQty3Qt9CwINCy0YvRgdC+0LrQvtC5INCz0L7QvNC+0YTQuNC70LjQuCDQsdC+0LvQtdC1INC80LXQu9C60LjRhSDRg9GH0LXQsdC90YvRhSDQt9Cw0LLQtdC00LXQvdC40LkuINCi0L7Qs9C00LAg0LzQvtC20L3QviDQv9GA0LXQtNC/0L7Qu9C+0LbQuNGC0YwsINGH0YLQviDQuNC80LXQvdC90L4g0L7QvdC4INC/0LvQvtGF0L4g0LLQt9Cw0LjQvNC+0LTQtdC50YHRgtCy0YPRjtGCINGBINCx0LjQt9C90LXRgdC+0Lwg0Lgg0LPQvtGBLiDQvtGA0LPQsNC90LDQvNC4LgoKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgojIyMjINCX0LDQutC70Y7Rh9C10L3QuNC1CgrQmtCw0Log0YLQvtCz0LTQsCDQvNC+0LbQvdC+INC40Lwg0L/QvtC80L7Rh9GMPyDQn9GA0Lgg0LzQvtC00LXQu9C40YDQvtCy0LDQvdC40Lgg0LjRhSDQutC70LDRgdGBINGA0LDRgdC/0YDQvtGB0YLRgNCw0L3Rj9C70YHRjyDQv9C+INGB0LXRgtC4INGH0LXRgNC10Lcg0LjRhSDRgdC+0YHQtdC00LXQuSAtLS0g0LrRgNGD0L/QvdGL0LUg0YPQvdC40LLQtdGA0YHQuNGC0LXRgtGLLiAqKtCSINGC0LDQutC+0Lwg0YHQu9GD0YfQsNC1LCDQsdC+0LvQtdC1INGA0LDQt9GD0LzQvdC+INGB0YLRgNC+0LjRgtGMINC90LDRg9GH0L3Ri9C1INGG0LXQvdGC0YDRiyDQuNC80LXQvdC90L4g0YHQvtC10LTQuNC90Y/RjtGJ0LjQtSDQvNC10LvQutC40LUg0YPQvdC40LLQtdGA0YHQuNGC0LXRgtGLINGBINC60YDRg9C/0L3Ri9C80LguINCU0LDQvdC90YvQvCDQvtCx0YDQsNC30L7QvCwg0LrQsNC30LDQu9C+0YHRjCDQsdGLLCDRg9GB0LjQu9C40LLQsNGPINCz0L7QvNC+0YTQuNC70LjRjiwg0LzRiywg0L3QsNC+0LHQvtGA0L7Rgiwg0LHRg9C00LXQvCDRgdC/0L7RgdC+0LHRgdGC0L7QstCw0YLRjCDRgNCw0LfQstC40YLQuNGOINC90LDRg9GH0L3Ri9GFINC+0YLQvdC+0YjQtdC90LjQuSDRg9C90LjQstC10YDRgdC40YLQtdGC0L7QsiDRgSDQuNC90LTRg9GB0YLRgNC40LDQu9GM0L3Ri9C80Lgg0L/QsNGA0YLQvdC10YDQsNC80LguKioKCtCX0LDQvNC10YfQsNC90LjQtQoKOiAgINCX0LTQtdGB0Ywg0LzRiyDQv9GA0LXQtNC/0L7Qu9Cw0LPQsNC10Lwg0Y3RgtCw0LvQvtC90L3QvtGB0YLRjCDQutGA0YPQv9C90YvRhSDRg9C90LjQstC10YDRgdC40YLQtdGC0L7QsiAo0L3QsNC/0YDQuNC80LXRgCwg0J7QutC70LXQvdC00YHQutC+0LPQvikg0YEg0YLQvtGH0LrQuCDQt9GA0LXQvdC40Y8g0Y3RhNGE0LXQutGC0LjQstC90L7RgdGC0Lgg0LLQt9Cw0LjQvNC+0LTQtdC50YHRgtCy0LjRjywg0LAg0YLQsNC60LbQtSDQutCw0YfQtdGB0YLQstCwINC4INC60L7Qu9C40YfQtdGB0YLQstCwINC90LDRg9GH0L3Ri9GFINGA0LDQsdC+0YIsINGH0YLQviDQv9GA0L7QtNC10LzQvtC90YHRgtGA0LjRgNC+0LLQsNC90L4sINC90LDQv9GA0LjQvNC10YAsINCyIFvRjdGC0L7QuSDRgdGC0LDRgtGM0LVdKGh0dHBzOi8vd3d3LnJlc2VhcmNoZ2F0ZS5uZXQvcHVibGljYXRpb24vMzI0MDkxMzU1X1doeV9TaG91bGRfVW5pdmVyc2l0eV9hbmRfQnVzaW5lc3NfQ29vcGVyYXRlX0FfRGlzY3Vzc2lvbl9vZl9BZHZhbnRhZ2VzX2FuZF9EaXNhZHZhbnRhZ2VzKS4K